Reset sender fault stats on first sync and hourly boundary

This commit is contained in:
2026-02-17 01:27:04 +01:00
parent d327f9b68a
commit 3aff6ea666

View File

@@ -122,6 +122,8 @@ static uint32_t g_meter_time_prev_seconds = 0;
static uint32_t g_meter_time_prev_rx_ms = 0;
static bool g_meter_time_jump_pending = false;
static bool g_time_acquired = false;
static bool g_sender_faults_reset_after_first_sync = false;
static uint32_t g_sender_faults_reset_hour_utc = UINT32_MAX;
static uint32_t g_last_sync_request_ms = 0;
static uint32_t g_build_attempts = 0;
static uint32_t g_build_valid = 0;
@@ -602,6 +604,52 @@ static void note_fault(FaultCounters &counters, FaultType &last_type, uint32_t &
last_ts_ms = millis();
}
static void clear_faults(FaultCounters &counters, FaultType &last_type, uint32_t &last_ts_utc, uint32_t &last_ts_ms) {
counters = {};
last_type = FaultType::None;
last_ts_utc = 0;
last_ts_ms = 0;
}
static void sender_reset_fault_stats(const char *reason, uint32_t now_utc) {
clear_faults(g_sender_faults, g_sender_last_error, g_sender_last_error_utc, g_sender_last_error_ms);
g_sender_rx_reject_reason = RxRejectReason::None;
display_set_last_error(g_sender_last_error, g_sender_last_error_utc, g_sender_last_error_ms);
if (SERIAL_DEBUG_MODE) {
serial_debug_printf("faults: reset scope=sender reason=%s ts_utc=%lu",
reason ? reason : "unknown",
static_cast<unsigned long>(now_utc));
}
}
static void sender_reset_fault_stats_on_first_sync(uint32_t synced_utc) {
if (g_sender_faults_reset_after_first_sync || synced_utc < MIN_ACCEPTED_EPOCH_UTC) {
return;
}
sender_reset_fault_stats("first_sync", synced_utc);
g_sender_faults_reset_after_first_sync = true;
g_sender_faults_reset_hour_utc = synced_utc / 3600U;
}
static void sender_reset_fault_stats_on_hour_boundary() {
if (!g_time_acquired || !g_sender_faults_reset_after_first_sync) {
return;
}
uint32_t now_utc = time_get_utc();
if (now_utc < MIN_ACCEPTED_EPOCH_UTC) {
return;
}
uint32_t now_hour_utc = now_utc / 3600U;
if (g_sender_faults_reset_hour_utc == UINT32_MAX) {
g_sender_faults_reset_hour_utc = now_hour_utc;
return;
}
if (now_hour_utc > g_sender_faults_reset_hour_utc) {
sender_reset_fault_stats("hourly", now_utc);
g_sender_faults_reset_hour_utc = now_hour_utc;
}
}
static uint32_t age_seconds(uint32_t ts_utc, uint32_t ts_ms) {
if (time_is_synced() && ts_utc > 0) {
uint32_t now = time_get_utc();
@@ -1241,6 +1289,8 @@ void setup() {
g_last_send_ms = millis();
g_last_sync_request_ms = millis() - SYNC_REQUEST_INTERVAL_MS;
g_time_acquired = false;
g_sender_faults_reset_after_first_sync = false;
g_sender_faults_reset_hour_utc = UINT32_MAX;
update_battery_cache();
} else {
power_receiver_init();
@@ -1287,6 +1337,7 @@ static void sender_loop() {
meter_reader_pump(now_ms);
if (g_time_acquired) {
sender_reset_fault_stats_on_hour_boundary();
while (now_ms - g_last_sample_ms >= METER_SAMPLE_INTERVAL_MS) {
g_last_sample_ms += METER_SAMPLE_INTERVAL_MS;
MeterData data = {};
@@ -1472,6 +1523,7 @@ static void sender_loop() {
if (time_valid == 1 && ack_epoch >= MIN_ACCEPTED_EPOCH_UTC) {
time_set_utc(ack_epoch);
g_time_acquired = true;
sender_reset_fault_stats_on_first_sync(ack_epoch);
set_time = true;
}
g_last_acked_batch_id = ack_id;