Add sender queue display and batch timing

This commit is contained in:
2026-02-01 17:46:26 +01:00
parent 430b0d7054
commit 22ed41b55c
4 changed files with 38 additions and 2 deletions

View File

@@ -11,6 +11,8 @@ void display_set_sender_statuses(const SenderStatus *statuses, uint8_t count);
void display_set_last_meter(const MeterData &data);
void display_set_last_read(bool ok, uint32_t ts_utc);
void display_set_last_tx(bool ok, uint32_t ts_utc);
void display_set_sender_queue(uint8_t depth, bool build_pending);
void display_set_sender_batches(uint16_t last_acked_batch_id, uint16_t current_batch_id);
void display_set_last_error(FaultType type, uint32_t ts_utc, uint32_t ts_ms);
void display_set_receiver_status(bool ap_mode, const char *ssid, bool mqtt_ok);
void display_power_down();

View File

@@ -19,6 +19,10 @@ static uint32_t g_last_read_ts = 0;
static uint32_t g_last_tx_ts = 0;
static uint32_t g_last_read_ms = 0;
static uint32_t g_last_tx_ms = 0;
static uint8_t g_sender_queue_depth = 0;
static bool g_sender_build_pending = false;
static uint16_t g_sender_last_acked_batch_id = 0;
static uint16_t g_sender_current_batch_id = 0;
static FaultType g_last_error = FaultType::None;
static uint32_t g_last_error_ts = 0;
static uint32_t g_last_error_ms = 0;
@@ -111,6 +115,16 @@ void display_set_last_tx(bool ok, uint32_t ts_utc) {
g_last_tx_ms = millis();
}
void display_set_sender_queue(uint8_t depth, bool build_pending) {
g_sender_queue_depth = depth;
g_sender_build_pending = build_pending;
}
void display_set_sender_batches(uint16_t last_acked_batch_id, uint16_t current_batch_id) {
g_sender_last_acked_batch_id = last_acked_batch_id;
g_sender_current_batch_id = current_batch_id;
}
void display_set_last_error(FaultType type, uint32_t ts_utc, uint32_t ts_ms) {
g_last_error = type;
g_last_error_ts = ts_utc;
@@ -195,7 +209,13 @@ static void render_sender_status() {
display.printf("Read %s %lus ago", g_last_read_ok ? "OK" : "ERR", static_cast<unsigned long>(age_seconds(g_last_read_ts, g_last_read_ms)));
display.setCursor(0, 36);
display.printf("TX %s %lus ago", g_last_tx_ok ? "OK" : "ERR", static_cast<unsigned long>(age_seconds(g_last_tx_ts, g_last_tx_ms)));
display.printf("TX %s %lus Q%u%s A%u C%u",
g_last_tx_ok ? "OK" : "ERR",
static_cast<unsigned long>(age_seconds(g_last_tx_ts, g_last_tx_ms)),
g_sender_queue_depth,
g_sender_build_pending ? "+" : "",
g_sender_last_acked_batch_id,
g_sender_current_batch_id);
#ifdef ENABLE_TEST_MODE
if (strlen(g_test_code) > 0) {

View File

@@ -183,6 +183,8 @@ bool meterBatchToJson(const MeterData *samples, size_t count, uint16_t batch_id,
doc["sender"] = sender_label;
doc["batch_id"] = batch_id;
doc["t0"] = samples[0].ts_utc;
doc["t_first"] = samples[0].ts_utc;
doc["t_last"] = samples[count - 1].ts_utc;
uint32_t dt_s = METER_SAMPLE_INTERVAL_MS / 1000;
doc["dt_s"] = dt_s > 0 ? dt_s : 1;
doc["n"] = static_cast<uint32_t>(count);
@@ -247,6 +249,8 @@ bool jsonToMeterBatch(const String &json, MeterData *out_samples, size_t max_cou
}
uint32_t t0 = doc["t0"] | 0;
uint32_t t_first = doc["t_first"] | t0;
uint32_t t_last = doc["t_last"] | t_first;
uint32_t dt_s = doc["dt_s"] | 1;
JsonArray energy = doc["energy_wh"].as<JsonArray>();
JsonArray p_w = doc["p_w"].as<JsonArray>();
@@ -268,7 +272,13 @@ bool jsonToMeterBatch(const String &json, MeterData *out_samples, size_t max_cou
snprintf(data.device_id, sizeof(data.device_id), "dd3-0000");
}
if (count > 1 && t_last >= t_first) {
uint32_t span = t_last - t_first;
uint32_t step = span / static_cast<uint32_t>(count - 1);
data.ts_utc = t_first + static_cast<uint32_t>(idx) * step;
} else {
data.ts_utc = t0 + static_cast<uint32_t>(idx) * dt_s;
}
data.energy_total_kwh = static_cast<float>((energy[idx] | 0)) / 1000.0f;
data.total_power_w = static_cast<float>(p_w[idx] | 0);
data.phase_power_w[0] = static_cast<float>(p1_w[idx] | 0);

View File

@@ -76,6 +76,7 @@ static uint8_t g_last_battery_percent = 0;
static uint32_t g_last_battery_ms = 0;
static uint16_t g_batch_id = 1;
static uint16_t g_last_sent_batch_id = 0;
static uint16_t g_last_acked_batch_id = 0;
static uint8_t g_batch_retry_count = 0;
static bool g_batch_ack_pending = false;
static MeterData g_inflight_samples[METER_BATCH_MAX_SAMPLES];
@@ -542,6 +543,8 @@ void setup() {
static void sender_loop() {
watchdog_kick();
uint32_t now_ms = millis();
display_set_sender_queue(g_batch_count, g_build_count > 0);
display_set_sender_batches(g_last_acked_batch_id, g_batch_id);
if (now_ms - g_last_sample_ms >= METER_SAMPLE_INTERVAL_MS) {
g_last_sample_ms = now_ms;
@@ -589,6 +592,7 @@ static void sender_loop() {
uint16_t ack_receiver = read_u16_le(&rx.payload[4]);
if (ack_sender == g_short_id && ack_receiver == rx.device_id_short &&
g_batch_ack_pending && ack_id == g_last_sent_batch_id) {
g_last_acked_batch_id = ack_id;
finish_inflight_batch();
}
}