Send batch ACKs immediately after reassembly

- Move ACK ahead of MQTT/web work to meet sender 400ms window
- Update ACK log format and document early-ACK behavior
This commit is contained in:
2026-02-04 00:36:40 +01:00
parent 4e06f7a96d
commit 0a99bf3268
2 changed files with 4 additions and 3 deletions

View File

@@ -237,6 +237,7 @@ Notes:
- Receiver reconstructs timestamps from `t_last` and `dt_s`. - Receiver reconstructs timestamps from `t_last` and `dt_s`.
- Total power is computed on receiver as `p1 + p2 + p3`. - Total power is computed on receiver as `p1 + p2 + p3`.
- Sender error counters are carried in the batch header and applied to all samples. - Sender error counters are carried in the batch header and applied to all samples.
- Receiver ACKs MeterBatch as soon as the batch is reassembled, before MQTT/web/UI work, to avoid missing the sender ACK window.
## Device IDs ## Device IDs
- Derived from WiFi STA MAC. - Derived from WiFi STA MAC.

View File

@@ -498,7 +498,7 @@ static void send_batch_ack(uint16_t batch_id, uint16_t sender_id) {
write_u16_le(&ack.payload[2], sender_id); write_u16_le(&ack.payload[2], sender_id);
write_u16_le(&ack.payload[4], g_short_id); write_u16_le(&ack.payload[4], g_short_id);
if (SERIAL_DEBUG_MODE) { if (SERIAL_DEBUG_MODE) {
serial_debug_printf("ack: tx batch_id=%u sender=%u receiver=%u", batch_id, sender_id, g_short_id); serial_debug_printf("ack: tx batch_id=%u to sender=%04X", batch_id, sender_id);
} }
lora_send(ack); lora_send(ack);
lora_receive_continuous(); lora_receive_continuous();
@@ -1007,6 +1007,8 @@ static void receiver_loop() {
if (duplicate) { if (duplicate) {
send_batch_ack(batch_id, pkt.device_id_short); send_batch_ack(batch_id, pkt.device_id_short);
} else { } else {
g_last_batch_id_rx[sender_idx] = batch_id;
send_batch_ack(batch_id, pkt.device_id_short);
count = batch.n; count = batch.n;
if (count == 0 || count > METER_BATCH_MAX_SAMPLES) { if (count == 0 || count > METER_BATCH_MAX_SAMPLES) {
note_fault(g_receiver_faults, g_receiver_last_error, g_receiver_last_error_utc, g_receiver_last_error_ms, FaultType::Decode); note_fault(g_receiver_faults, g_receiver_last_error, g_receiver_last_error_utc, g_receiver_last_error_ms, FaultType::Decode);
@@ -1080,8 +1082,6 @@ static void receiver_loop() {
g_sender_last_error_remote[sender_idx], g_sender_last_error_remote_published[sender_idx], g_sender_last_error_remote[sender_idx], g_sender_last_error_remote_published[sender_idx],
g_sender_last_error_remote_utc[sender_idx], g_sender_last_error_remote_ms[sender_idx]); g_sender_last_error_remote_utc[sender_idx], g_sender_last_error_remote_ms[sender_idx]);
} }
g_last_batch_id_rx[sender_idx] = batch_id;
send_batch_ack(batch_id, pkt.device_id_short);
} }
} }
} else if (decode_error) { } else if (decode_error) {