Dosyalar
MeshCoreTel-firmware/src/helpers/StatsHistory.h
T

174 satır
5.3 KiB
C++

#pragma once
#include <Arduino.h>
#include <MeshCore.h>
#include "ArchiveStorage.h"
struct HistorySample {
uint32_t epoch_secs;
uint32_t uptime_secs;
uint32_t packets_sent;
uint32_t packets_recv;
uint32_t heap_free;
uint32_t heap_min;
uint32_t psram_free;
uint32_t psram_min;
uint16_t battery_mv;
uint16_t queue_len;
uint16_t error_flags;
uint16_t recv_errors;
uint16_t neighbour_count;
uint16_t direct_dups;
uint16_t flood_dups;
int16_t last_rssi_x4;
int16_t last_snr_x4;
int16_t noise_floor;
uint16_t supply_voltage_centi_v;
int16_t sensor_temp_deci_c;
int16_t mcu_temp_deci_c;
uint16_t humidity_deci_pct;
uint16_t pressure_deci_hpa;
int16_t pressure_altitude_m;
int16_t gps_altitude_m;
int32_t gps_lat_e6;
int32_t gps_lon_e6;
uint16_t sensor_flags;
uint8_t gps_satellites;
uint8_t flags;
int8_t battery_pct;
uint8_t reserved;
};
struct HistoryEvent {
uint32_t epoch_secs;
uint32_t uptime_secs;
uint8_t type;
int16_t value;
uint8_t reserved;
};
enum HistorySampleFlags : uint8_t {
HISTORY_FLAG_EXTERNAL_POWER = 1 << 0,
HISTORY_FLAG_CHARGING = 1 << 1,
HISTORY_FLAG_VBUS = 1 << 2,
HISTORY_FLAG_WIFI_CONNECTED = 1 << 3,
HISTORY_FLAG_MQTT_CONNECTED = 1 << 4,
HISTORY_FLAG_WEB_ENABLED = 1 << 5,
HISTORY_FLAG_WEB_PANEL_UP = 1 << 6,
HISTORY_FLAG_ARCHIVE_MOUNTED = 1 << 7,
};
enum HistorySampleSensorFlags : uint16_t {
HISTORY_SENSOR_SUPPLY_VOLTAGE = 1 << 0,
HISTORY_SENSOR_TEMP = 1 << 1,
HISTORY_SENSOR_MCU_TEMP = 1 << 2,
HISTORY_SENSOR_HUMIDITY = 1 << 3,
HISTORY_SENSOR_PRESSURE = 1 << 4,
HISTORY_SENSOR_PRESSURE_ALTITUDE = 1 << 5,
HISTORY_SENSOR_GPS_PRESENT = 1 << 6,
HISTORY_SENSOR_GPS_ENABLED = 1 << 7,
HISTORY_SENSOR_GPS_FIX = 1 << 8,
HISTORY_SENSOR_GPS_LAT = 1 << 9,
HISTORY_SENSOR_GPS_LON = 1 << 10,
HISTORY_SENSOR_GPS_ALTITUDE = 1 << 11,
HISTORY_SENSOR_GPS_SATELLITES = 1 << 12,
};
enum HistoryEventType : uint8_t {
HISTORY_EVENT_BOOT = 1,
HISTORY_EVENT_WEB_STARTED = 2,
HISTORY_EVENT_WEB_STOPPED = 3,
HISTORY_EVENT_MQTT_CONNECTED = 4,
HISTORY_EVENT_MQTT_DISCONNECTED = 5,
HISTORY_EVENT_ARCHIVE_MOUNTED = 6,
HISTORY_EVENT_ARCHIVE_UNAVAILABLE = 7,
HISTORY_EVENT_LOW_MEMORY = 8,
HISTORY_EVENT_STATS_ENABLED = 9,
HISTORY_EVENT_STATS_DISABLED = 10,
};
class StatsHistory {
public:
static constexpr uint32_t kSampleIntervalSecs = 60;
static constexpr uint32_t kArchiveSummaryIntervalSecs = 300;
static constexpr uint32_t kLiveOnlyIdleTimeoutMs = 2UL * 60UL * 1000UL;
StatsHistory();
~StatsHistory();
void begin(bool enabled, ArchiveStorage* archive);
void setArchive(ArchiveStorage* archive);
void setEnabled(bool enabled);
bool isEnabled() const { return _enabled; }
bool isRecentHistoryAvailable() const { return _samples != nullptr; }
bool isPsramBacked() const { return _psram_backed; }
bool isDegraded() const { return _degraded; }
bool isLiveOnly() const { return _live_only; }
bool isArchiveAvailable() const;
bool hasArchiveRestore() const { return _restored_sample_count > 0; }
bool isBootAutoCaptureExpected() const;
uint32_t getDetectedPsramSizeBytes() const;
size_t getSampleCapacity() const { return _sample_capacity; }
size_t getSampleCount() const { return _sample_count; }
size_t getEventCapacity() const { return _event_capacity; }
size_t getEventCount() const { return _event_count; }
size_t getRestoredSampleCount() const { return _restored_sample_count; }
void pushSample(const HistorySample& sample);
void recordEvent(uint8_t type, uint32_t epoch_secs, uint32_t uptime_secs, int16_t value = 0);
void maybeFlush(uint32_t now_ms);
void noteAccess(uint32_t now_ms);
void maybeReleaseIdleBuffers(uint32_t now_ms);
bool buildSeriesJson(const char* series, char* buffer, size_t buffer_size, uint32_t now_epoch_secs, uint32_t now_uptime_secs) const;
bool getRecentEvent(size_t reverse_index, HistoryEvent& event) const;
static const char* getEventTypeName(uint8_t type);
static constexpr uint32_t getSampleIntervalSecs() { return kSampleIntervalSecs; }
static constexpr uint32_t getArchiveSummaryIntervalSecs() { return kArchiveSummaryIntervalSecs; }
private:
bool activate();
bool ensureBuffers();
void releaseBuffers();
bool supportsPersistence() const;
bool shouldAutoActivateFromBoot() const;
bool isAccessActive(uint32_t now_ms) const;
bool restoreSummaryLog();
bool restoreEventsLog();
bool parseSummaryLine(const char* line, HistorySample& sample) const;
bool parseEventLine(const char* line, HistoryEvent& event) const;
void storeSample(const HistorySample& sample, bool mark_dirty);
void storeEvent(const HistoryEvent& event, bool queue_pending);
void appendPendingEvent(const HistoryEvent& event);
void flushSummaryLog();
void flushEventsLog();
void writeMetaFile() const;
bool getSampleFromOldest(size_t index, HistorySample& sample) const;
bool _enabled;
bool _activated;
bool _psram_backed;
bool _degraded;
bool _live_only;
bool _summary_dirty;
uint32_t _next_summary_flush_ms;
uint32_t _next_event_flush_ms;
uint32_t _last_access_ms;
size_t _sample_capacity;
size_t _sample_head;
size_t _sample_count;
size_t _event_capacity;
size_t _event_head;
size_t _event_count;
HistorySample* _samples;
HistoryEvent* _events;
ArchiveStorage* _archive;
size_t _restored_sample_count;
HistoryEvent _pending_events[16];
size_t _pending_event_count;
};