mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-04 02:09:30 +02:00
Optimize Event Ordering by Storing Milliseconds and Handling Rollovers
This commit is contained in:
parent
6c7d7c5b78
commit
086c3dfa29
6 changed files with 83 additions and 74 deletions
|
@ -60,6 +60,8 @@ SensorConfig sensorConfigs[] = {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::vector<EventData> order_events;
|
||||||
|
|
||||||
static String generateCommonInfoAutoConfigTopic(const char* object_id, const char* hostname) {
|
static String generateCommonInfoAutoConfigTopic(const char* object_id, const char* hostname) {
|
||||||
return String("homeassistant/sensor/battery-emulator_") + String(hostname) + "/" + String(object_id) + "/config";
|
return String("homeassistant/sensor/battery-emulator_") + String(hostname) + "/" + String(object_id) + "/config";
|
||||||
}
|
}
|
||||||
|
@ -233,7 +235,7 @@ void publish_events() {
|
||||||
doc["unique_id"] = "battery-emulator_" + String(hostname) + "_event";
|
doc["unique_id"] = "battery-emulator_" + String(hostname) + "_event";
|
||||||
doc["object_id"] = String(hostname) + "_event";
|
doc["object_id"] = String(hostname) + "_event";
|
||||||
doc["value_template"] =
|
doc["value_template"] =
|
||||||
"{{ value_json.event_type ~ ' (c:' ~ value_json.count ~ ',m:' ~ value_json.milis ~ ') ' ~ value_json.message "
|
"{{ value_json.event_type ~ ' (c:' ~ value_json.count ~ ',m:' ~ value_json.millis ~ ') ' ~ value_json.message "
|
||||||
"}}";
|
"}}";
|
||||||
doc["json_attributes_topic"] = state_topic;
|
doc["json_attributes_topic"] = state_topic;
|
||||||
doc["json_attributes_template"] = "{{ value_json | tojson }}";
|
doc["json_attributes_template"] = "{{ value_json | tojson }}";
|
||||||
|
@ -253,36 +255,43 @@ void publish_events() {
|
||||||
#endif // HA_AUTODISCOVERY
|
#endif // HA_AUTODISCOVERY
|
||||||
|
|
||||||
const EVENTS_STRUCT_TYPE* event_pointer;
|
const EVENTS_STRUCT_TYPE* event_pointer;
|
||||||
unsigned long timestamp_now = get_current_event_time_secs();
|
|
||||||
|
|
||||||
|
//clear the vector
|
||||||
|
order_events.clear();
|
||||||
|
// Collect all events
|
||||||
for (int i = 0; i < EVENT_NOF_EVENTS; i++) {
|
for (int i = 0; i < EVENT_NOF_EVENTS; i++) {
|
||||||
event_pointer = get_event_pointer((EVENTS_ENUM_TYPE)i);
|
event_pointer = get_event_pointer((EVENTS_ENUM_TYPE)i);
|
||||||
EVENTS_ENUM_TYPE event_handle = static_cast<EVENTS_ENUM_TYPE>(i);
|
|
||||||
|
|
||||||
if (event_pointer->occurences > 0 && !event_pointer->MQTTpublished) {
|
if (event_pointer->occurences > 0 && !event_pointer->MQTTpublished) {
|
||||||
|
order_events.push_back({static_cast<EVENTS_ENUM_TYPE>(i), event_pointer});
|
||||||
doc["event_type"] = String(get_event_enum_string(event_handle));
|
|
||||||
doc["severity"] = String(get_event_level_string(event_handle));
|
|
||||||
|
|
||||||
time_t time_difference = timestamp_now - event_pointer->timestamp;
|
|
||||||
|
|
||||||
doc["last_event"] = String(timestamp_now - event_pointer->timestamp);
|
|
||||||
doc["count"] = String(event_pointer->occurences);
|
|
||||||
doc["data"] = String(event_pointer->data);
|
|
||||||
doc["message"] = String(get_event_message_string(event_handle));
|
|
||||||
doc["milis"] = String(millis());
|
|
||||||
|
|
||||||
serializeJson(doc, mqtt_msg);
|
|
||||||
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
|
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
Serial.println("Common info MQTT msg could not be sent");
|
|
||||||
#endif // DEBUG_VIA_USB
|
|
||||||
} else {
|
|
||||||
set_event_MQTTpublished(event_handle);
|
|
||||||
}
|
|
||||||
doc.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Sort events by timestamp
|
||||||
|
std::sort(order_events.begin(), order_events.end(), compareEventsByTimestamp);
|
||||||
|
|
||||||
|
for (const auto& event : order_events) {
|
||||||
|
|
||||||
|
EVENTS_ENUM_TYPE event_handle = event.event_handle;
|
||||||
|
event_pointer = event.event_pointer;
|
||||||
|
|
||||||
|
doc["event_type"] = String(get_event_enum_string(event_handle));
|
||||||
|
doc["severity"] = String(get_event_level_string(event_handle));
|
||||||
|
doc["count"] = String(event_pointer->occurences);
|
||||||
|
doc["data"] = String(event_pointer->data);
|
||||||
|
doc["message"] = String(get_event_message_string(event_handle));
|
||||||
|
doc["millis"] = String(event_pointer->timestamp);
|
||||||
|
|
||||||
|
serializeJson(doc, mqtt_msg);
|
||||||
|
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
|
||||||
|
#ifdef DEBUG_VIA_USB
|
||||||
|
Serial.println("Common info MQTT msg could not be sent");
|
||||||
|
#endif // DEBUG_VIA_USB
|
||||||
|
} else {
|
||||||
|
set_event_MQTTpublished(event_handle);
|
||||||
|
}
|
||||||
|
doc.clear();
|
||||||
|
//clear the vector
|
||||||
|
order_events.clear();
|
||||||
|
}
|
||||||
#ifdef HA_AUTODISCOVERY
|
#ifdef HA_AUTODISCOVERY
|
||||||
}
|
}
|
||||||
#endif // HA_AUTODISCOVERY
|
#endif // HA_AUTODISCOVERY
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#define __MQTT_H__
|
#define __MQTT_H__
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <vector>
|
||||||
#include "../../include.h"
|
#include "../../include.h"
|
||||||
|
|
||||||
#define MQTT_MSG_BUFFER_SIZE (1024)
|
#define MQTT_MSG_BUFFER_SIZE (1024)
|
||||||
|
|
|
@ -44,16 +44,14 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
EVENTS_ENUM_TYPE event;
|
EVENTS_ENUM_TYPE event;
|
||||||
|
uint8_t millisrolloverCount;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
} EVENT_LOG_ENTRY_TYPE;
|
} EVENT_LOG_ENTRY_TYPE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS];
|
EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS];
|
||||||
unsigned long time_seconds;
|
|
||||||
MyTimer second_timer;
|
|
||||||
MyTimer ee_timer;
|
MyTimer ee_timer;
|
||||||
MyTimer update_timer;
|
|
||||||
EVENTS_LEVEL_TYPE level;
|
EVENTS_LEVEL_TYPE level;
|
||||||
uint16_t event_log_head_index;
|
uint16_t event_log_head_index;
|
||||||
uint16_t event_log_tail_index;
|
uint16_t event_log_tail_index;
|
||||||
|
@ -66,21 +64,29 @@ static EVENT_TYPE events;
|
||||||
static const char* EVENTS_ENUM_TYPE_STRING[] = {EVENTS_ENUM_TYPE(GENERATE_STRING)};
|
static const char* EVENTS_ENUM_TYPE_STRING[] = {EVENTS_ENUM_TYPE(GENERATE_STRING)};
|
||||||
static const char* EVENTS_LEVEL_TYPE_STRING[] = {EVENTS_LEVEL_TYPE(GENERATE_STRING)};
|
static const char* EVENTS_LEVEL_TYPE_STRING[] = {EVENTS_LEVEL_TYPE(GENERATE_STRING)};
|
||||||
|
|
||||||
|
static uint32_t lastMillis = millis();
|
||||||
|
|
||||||
/* Local function prototypes */
|
/* Local function prototypes */
|
||||||
static void update_event_time(void);
|
|
||||||
static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched);
|
static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched);
|
||||||
static void update_event_level(void);
|
static void update_event_level(void);
|
||||||
static void update_bms_status(void);
|
static void update_bms_status(void);
|
||||||
|
|
||||||
static void log_event(EVENTS_ENUM_TYPE event, uint8_t data);
|
static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint32_t timestamp, uint8_t data);
|
||||||
static void print_event_log(void);
|
static void print_event_log(void);
|
||||||
static void check_ee_write(void);
|
static void check_ee_write(void);
|
||||||
|
|
||||||
|
uint8_t millisrolloverCount = 0;
|
||||||
|
|
||||||
/* Exported functions */
|
/* Exported functions */
|
||||||
|
|
||||||
/* Main execution function, should handle various continuous functionality */
|
/* Main execution function, should handle various continuous functionality */
|
||||||
void run_event_handling(void) {
|
void run_event_handling(void) {
|
||||||
update_event_time();
|
uint32_t currentMillis = millis();
|
||||||
|
if (currentMillis < lastMillis) { // Overflow detected
|
||||||
|
millisrolloverCount++;
|
||||||
|
}
|
||||||
|
lastMillis = currentMillis;
|
||||||
|
|
||||||
run_sequence_on_target();
|
run_sequence_on_target();
|
||||||
//check_ee_write();
|
//check_ee_write();
|
||||||
update_event_level();
|
update_event_level();
|
||||||
|
@ -100,7 +106,7 @@ void init_events(void) {
|
||||||
EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, 0);
|
EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, 0);
|
||||||
|
|
||||||
// Prepare an empty event block to write
|
// Prepare an empty event block to write
|
||||||
EVENT_LOG_ENTRY_TYPE entry = {.event = EVENT_NOF_EVENTS, .timestamp = 0, .data = 0};
|
EVENT_LOG_ENTRY_TYPE entry = {.event = EVENT_NOF_EVENTS, .millisrolloverCount = 0, .timestamp = 0, .data = 0};
|
||||||
|
|
||||||
// Put the event in (what I guess is) the RAM EEPROM mirror, or write buffer
|
// Put the event in (what I guess is) the RAM EEPROM mirror, or write buffer
|
||||||
|
|
||||||
|
@ -128,6 +134,7 @@ void init_events(void) {
|
||||||
for (uint16_t i = 0; i < EVENT_NOF_EVENTS; i++) {
|
for (uint16_t i = 0; i < EVENT_NOF_EVENTS; i++) {
|
||||||
events.entries[i].data = 0;
|
events.entries[i].data = 0;
|
||||||
events.entries[i].timestamp = 0;
|
events.entries[i].timestamp = 0;
|
||||||
|
events.entries[i].millisrolloverCount = 0;
|
||||||
events.entries[i].occurences = 0;
|
events.entries[i].occurences = 0;
|
||||||
events.entries[i].log = true;
|
events.entries[i].log = true;
|
||||||
events.entries[i].MQTTpublished = false; // Not published by default
|
events.entries[i].MQTTpublished = false; // Not published by default
|
||||||
|
@ -206,10 +213,8 @@ void init_events(void) {
|
||||||
|
|
||||||
events.entries[EVENT_EEPROM_WRITE].log = false; // Don't log the logger...
|
events.entries[EVENT_EEPROM_WRITE].log = false; // Don't log the logger...
|
||||||
|
|
||||||
events.second_timer.set_interval(600);
|
|
||||||
// Write to EEPROM every X minutes (if an event has been set)
|
// Write to EEPROM every X minutes (if an event has been set)
|
||||||
events.ee_timer.set_interval(EE_WRITE_PERIOD_MINUTES * 60 * 1000);
|
events.ee_timer.set_interval(EE_WRITE_PERIOD_MINUTES * 60 * 1000);
|
||||||
events.update_timer.set_interval(2000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_event(EVENTS_ENUM_TYPE event, uint8_t data) {
|
void set_event(EVENTS_ENUM_TYPE event, uint8_t data) {
|
||||||
|
@ -419,12 +424,13 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) {
|
||||||
events.entries[event].occurences++;
|
events.entries[event].occurences++;
|
||||||
events.entries[event].MQTTpublished = false;
|
events.entries[event].MQTTpublished = false;
|
||||||
if (events.entries[event].log) {
|
if (events.entries[event].log) {
|
||||||
log_event(event, data);
|
log_event(event, events.entries[event].millisrolloverCount, events.entries[event].timestamp, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should set the event, update event info
|
// We should set the event, update event info
|
||||||
events.entries[event].timestamp = events.time_seconds;
|
events.entries[event].timestamp = millis();
|
||||||
|
events.entries[event].millisrolloverCount = millisrolloverCount;
|
||||||
events.entries[event].data = data;
|
events.entries[event].data = data;
|
||||||
// Check if the event is latching
|
// Check if the event is latching
|
||||||
events.entries[event].state = latched ? EVENT_STATE_ACTIVE_LATCHED : EVENT_STATE_ACTIVE;
|
events.entries[event].state = latched ? EVENT_STATE_ACTIVE_LATCHED : EVENT_STATE_ACTIVE;
|
||||||
|
@ -457,6 +463,14 @@ static void update_bms_status(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to compare events by timestamp
|
||||||
|
bool compareEventsByTimestamp(const EventData& a, const EventData& b) {
|
||||||
|
if (a.event_pointer->millisrolloverCount != b.event_pointer->millisrolloverCount) {
|
||||||
|
return a.event_pointer->millisrolloverCount > b.event_pointer->millisrolloverCount;
|
||||||
|
}
|
||||||
|
return a.event_pointer->timestamp > b.event_pointer->timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
static void update_event_level(void) {
|
static void update_event_level(void) {
|
||||||
EVENTS_LEVEL_TYPE temporary_level = EVENT_LEVEL_INFO;
|
EVENTS_LEVEL_TYPE temporary_level = EVENT_LEVEL_INFO;
|
||||||
for (uint8_t i = 0u; i < EVENT_NOF_EVENTS; i++) {
|
for (uint8_t i = 0u; i < EVENT_NOF_EVENTS; i++) {
|
||||||
|
@ -467,22 +481,7 @@ static void update_event_level(void) {
|
||||||
events.level = temporary_level;
|
events.level = temporary_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_event_time(void) {
|
static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint32_t timestamp, uint8_t data) {
|
||||||
// This should run roughly 2 times per second
|
|
||||||
if (events.second_timer.elapsed() == true) {
|
|
||||||
uptime::calculateUptime(); // millis() overflows every 50 days, so update occasionally to adjust
|
|
||||||
events.time_seconds = uptime::getDays() * DAYS_TO_SECS;
|
|
||||||
events.time_seconds += uptime::getHours() * HOURS_TO_SECS;
|
|
||||||
events.time_seconds += uptime::getMinutes() * MINUTES_TO_SECS;
|
|
||||||
events.time_seconds += uptime::getSeconds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long get_current_event_time_secs(void) {
|
|
||||||
return events.time_seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void log_event(EVENTS_ENUM_TYPE event, uint8_t data) {
|
|
||||||
// Update head with wrap to 0
|
// Update head with wrap to 0
|
||||||
if (++events.event_log_head_index == EE_NOF_EVENT_ENTRIES) {
|
if (++events.event_log_head_index == EE_NOF_EVENT_ENTRIES) {
|
||||||
events.event_log_head_index = 0;
|
events.event_log_head_index = 0;
|
||||||
|
@ -500,7 +499,8 @@ static void log_event(EVENTS_ENUM_TYPE event, uint8_t data) {
|
||||||
int entry_address = EE_EVENT_ENTRY_START_ADDRESS + EE_EVENT_ENTRY_SIZE * events.event_log_head_index;
|
int entry_address = EE_EVENT_ENTRY_START_ADDRESS + EE_EVENT_ENTRY_SIZE * events.event_log_head_index;
|
||||||
|
|
||||||
// Prepare an event block to write
|
// Prepare an event block to write
|
||||||
EVENT_LOG_ENTRY_TYPE entry = {.event = event, .timestamp = events.time_seconds, .data = data};
|
EVENT_LOG_ENTRY_TYPE entry = {
|
||||||
|
.event = event, .millisrolloverCount = millisrolloverCount, .timestamp = timestamp, .data = data};
|
||||||
|
|
||||||
// Put the event in (what I guess is) the RAM EEPROM mirror, or write buffer
|
// Put the event in (what I guess is) the RAM EEPROM mirror, or write buffer
|
||||||
EEPROM.put(entry_address, entry);
|
EEPROM.put(entry_address, entry);
|
||||||
|
|
|
@ -120,20 +120,28 @@ typedef enum {
|
||||||
} EVENTS_STATE_TYPE;
|
} EVENTS_STATE_TYPE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t timestamp; // Time in seconds since startup when the event occurred
|
uint32_t timestamp; // Time in seconds since startup when the event occurred
|
||||||
uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage
|
uint8_t millisrolloverCount; // number of times millis rollovers before timestamp
|
||||||
uint8_t occurences; // Number of occurrences since startup
|
uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage
|
||||||
EVENTS_LEVEL_TYPE level; // Event level, i.e. ERROR/WARNING...
|
uint8_t occurences; // Number of occurrences since startup
|
||||||
EVENTS_STATE_TYPE state; // Event state, i.e. ACTIVE/INACTIVE...
|
EVENTS_LEVEL_TYPE level; // Event level, i.e. ERROR/WARNING...
|
||||||
|
EVENTS_STATE_TYPE state; // Event state, i.e. ACTIVE/INACTIVE...
|
||||||
bool log;
|
bool log;
|
||||||
bool MQTTpublished;
|
bool MQTTpublished;
|
||||||
} EVENTS_STRUCT_TYPE;
|
} EVENTS_STRUCT_TYPE;
|
||||||
|
|
||||||
|
// Define a struct to hold event data
|
||||||
|
struct EventData {
|
||||||
|
EVENTS_ENUM_TYPE event_handle;
|
||||||
|
const EVENTS_STRUCT_TYPE* event_pointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern uint8_t millisrolloverCount; // number of times millis rollovers
|
||||||
|
|
||||||
const char* get_event_enum_string(EVENTS_ENUM_TYPE event);
|
const char* get_event_enum_string(EVENTS_ENUM_TYPE event);
|
||||||
const char* get_event_message_string(EVENTS_ENUM_TYPE event);
|
const char* get_event_message_string(EVENTS_ENUM_TYPE event);
|
||||||
const char* get_event_level_string(EVENTS_ENUM_TYPE event);
|
const char* get_event_level_string(EVENTS_ENUM_TYPE event);
|
||||||
const char* get_event_type(EVENTS_ENUM_TYPE event);
|
const char* get_event_type(EVENTS_ENUM_TYPE event);
|
||||||
unsigned long get_current_event_time_secs(void);
|
|
||||||
|
|
||||||
EVENTS_LEVEL_TYPE get_event_level(void);
|
EVENTS_LEVEL_TYPE get_event_level(void);
|
||||||
|
|
||||||
|
@ -149,4 +157,6 @@ void run_event_handling(void);
|
||||||
|
|
||||||
void run_sequence_on_target(void);
|
void run_sequence_on_target(void);
|
||||||
|
|
||||||
|
bool compareEventsByTimestamp(const EventData& a, const EventData& b);
|
||||||
|
|
||||||
#endif // __MYTIMER_H__
|
#endif // __MYTIMER_H__
|
||||||
|
|
|
@ -7,16 +7,11 @@ const char EVENTS_HTML_END[] = R"=====(
|
||||||
</div></div>
|
</div></div>
|
||||||
<button onclick='home()'>Back to main page</button>
|
<button onclick='home()'>Back to main page</button>
|
||||||
<style>.event:nth-child(even){background-color:#455a64}.event:nth-child(odd){background-color:#394b52}</style>
|
<style>.event:nth-child(even){background-color:#455a64}.event:nth-child(odd){background-color:#394b52}</style>
|
||||||
<script>function showEvent(){document.querySelectorAll(".event").forEach(function(e){var n=e.querySelector(".sec-ago");n&&(n.innerText=new Date(new Date().getTime()-1e3*parseInt(n.innerText,10)).toLocaleString())})}function home(){window.location.href="/"}window.onload=function(){showEvent()}</script>
|
<script>function showEvent(){document.querySelectorAll(".event").forEach(function(e){var n=e.querySelector(".sec-ago");n&&(n.innerText=new Date(Date.now()-((+n.innerText.split(';')[0])*4294967296+ +n.innerText.split(';')[1])).toLocaleString());})}function home(){window.location.href="/"}window.onload=function(){showEvent()}</script>
|
||||||
)=====";
|
)=====";
|
||||||
|
|
||||||
static std::vector<EventData> order_events;
|
static std::vector<EventData> order_events;
|
||||||
|
|
||||||
// Function to compare events by timestamp
|
|
||||||
static bool compareEventsByTimestamp(const EventData& a, const EventData& b) {
|
|
||||||
return a.event_pointer->timestamp > b.event_pointer->timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
String events_processor(const String& var) {
|
String events_processor(const String& var) {
|
||||||
if (var == "X") {
|
if (var == "X") {
|
||||||
String content = "";
|
String content = "";
|
||||||
|
@ -25,8 +20,6 @@ String events_processor(const String& var) {
|
||||||
content.concat(FPSTR(EVENTS_HTML_START));
|
content.concat(FPSTR(EVENTS_HTML_START));
|
||||||
const EVENTS_STRUCT_TYPE* event_pointer;
|
const EVENTS_STRUCT_TYPE* event_pointer;
|
||||||
|
|
||||||
unsigned long timestamp_now = get_current_event_time_secs();
|
|
||||||
|
|
||||||
//clear the vector
|
//clear the vector
|
||||||
order_events.clear();
|
order_events.clear();
|
||||||
// Collect all events
|
// Collect all events
|
||||||
|
@ -36,9 +29,9 @@ String events_processor(const String& var) {
|
||||||
order_events.push_back({static_cast<EVENTS_ENUM_TYPE>(i), event_pointer});
|
order_events.push_back({static_cast<EVENTS_ENUM_TYPE>(i), event_pointer});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort events by timestamp
|
// Sort events by timestamp
|
||||||
std::sort(order_events.begin(), order_events.end(), compareEventsByTimestamp);
|
std::sort(order_events.begin(), order_events.end(), compareEventsByTimestamp);
|
||||||
|
unsigned long timestamp_now = millis();
|
||||||
|
|
||||||
// Generate HTML and debug output
|
// Generate HTML and debug output
|
||||||
for (const auto& event : order_events) {
|
for (const auto& event : order_events) {
|
||||||
|
@ -53,7 +46,8 @@ String events_processor(const String& var) {
|
||||||
content.concat("<div class='event'>");
|
content.concat("<div class='event'>");
|
||||||
content.concat("<div>" + String(get_event_enum_string(event_handle)) + "</div>");
|
content.concat("<div>" + String(get_event_enum_string(event_handle)) + "</div>");
|
||||||
content.concat("<div>" + String(get_event_level_string(event_handle)) + "</div>");
|
content.concat("<div>" + String(get_event_level_string(event_handle)) + "</div>");
|
||||||
content.concat("<div class='sec-ago'>" + String(timestamp_now - event_pointer->timestamp) + "</div>");
|
content.concat("<div class='sec-ago'>" + String(millisrolloverCount) + ";" +
|
||||||
|
String(timestamp_now - event_pointer->timestamp) + "</div>");
|
||||||
content.concat("<div>" + String(event_pointer->occurences) + "</div>");
|
content.concat("<div>" + String(event_pointer->occurences) + "</div>");
|
||||||
content.concat("<div>" + String(event_pointer->data) + "</div>");
|
content.concat("<div>" + String(event_pointer->data) + "</div>");
|
||||||
content.concat("<div>" + String(get_event_message_string(event_handle)) + "</div>");
|
content.concat("<div>" + String(get_event_message_string(event_handle)) + "</div>");
|
||||||
|
|
|
@ -14,10 +14,5 @@
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
String events_processor(const String& var);
|
String events_processor(const String& var);
|
||||||
// Define a struct to hold event data
|
|
||||||
struct EventData {
|
|
||||||
EVENTS_ENUM_TYPE event_handle;
|
|
||||||
const EVENTS_STRUCT_TYPE* event_pointer;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue