adjust batch ack timing and rename e_wh field

This commit is contained in:
2026-02-01 21:53:18 +01:00
parent 01f4494f00
commit d27b68c1cc
3 changed files with 40 additions and 4 deletions

View File

@@ -81,6 +81,7 @@ 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 uint32_t g_batch_ack_timeout_ms = BATCH_ACK_TIMEOUT_MS;
static MeterData g_inflight_samples[METER_BATCH_MAX_SAMPLES];
static uint8_t g_inflight_count = 0;
static uint16_t g_inflight_batch_id = 0;
@@ -294,6 +295,17 @@ static uint32_t compute_batch_rx_timeout_ms(uint16_t total_len, uint8_t chunk_co
return timeout_ms < 10000 ? 10000 : timeout_ms;
}
static uint32_t compute_batch_ack_timeout_ms(size_t payload_len) {
if (payload_len == 0) {
return 10000;
}
uint8_t chunk_count = static_cast<uint8_t>((payload_len + BATCH_CHUNK_PAYLOAD - 1) / BATCH_CHUNK_PAYLOAD);
size_t packet_len = 5 + BATCH_HEADER_SIZE + (payload_len > BATCH_CHUNK_PAYLOAD ? BATCH_CHUNK_PAYLOAD : payload_len) + 2;
uint32_t per_chunk_toa_ms = lora_airtime_ms(packet_len);
uint32_t timeout_ms = static_cast<uint32_t>(chunk_count) * per_chunk_toa_ms + BATCH_RX_MARGIN_MS;
return timeout_ms < 10000 ? 10000 : timeout_ms;
}
static bool inject_batch_meta(String &json, int16_t rssi_dbm, float snr_db, uint32_t rx_ts_utc) {
DynamicJsonDocument doc(8192);
DeserializationError err = deserializeJson(doc, json);
@@ -423,6 +435,7 @@ static bool send_inflight_batch(uint32_t ts_for_display) {
if (SERIAL_DEBUG_MODE && compress_ms > 200) {
serial_debug_printf("tx: compress took %lums", static_cast<unsigned long>(compress_ms));
}
g_batch_ack_timeout_ms = compute_batch_ack_timeout_ms(compressed_len);
uint32_t send_start = millis();
bool ok = send_batch_payload(compressed, compressed_len, ts_for_display, g_inflight_batch_id);
@@ -668,6 +681,29 @@ static void sender_loop() {
send_meter_batch(last_sample_ts());
}
if (g_batch_ack_pending) {
uint32_t end_ms = millis() + 400;
while (millis() < end_ms) {
LoraPacket ack_pkt = {};
if (!lora_receive(ack_pkt, 0) || ack_pkt.protocol_version != PROTOCOL_VERSION) {
delay(5);
continue;
}
if (ack_pkt.payload_type == PayloadType::Ack && ack_pkt.payload_len >= 6 && ack_pkt.role == DeviceRole::Receiver) {
uint16_t ack_id = read_u16_le(ack_pkt.payload);
uint16_t ack_sender = read_u16_le(&ack_pkt.payload[2]);
uint16_t ack_receiver = read_u16_le(&ack_pkt.payload[4]);
if (ack_sender == g_short_id && ack_receiver == ack_pkt.device_id_short &&
g_batch_ack_pending && ack_id == g_last_sent_batch_id) {
g_last_acked_batch_id = ack_id;
serial_debug_printf("ack: ok batch_id=%u", ack_id);
finish_inflight_batch();
break;
}
}
}
}
LoraPacket rx = {};
if (lora_receive(rx, 0) && rx.protocol_version == PROTOCOL_VERSION) {
if (rx.payload_type == PayloadType::TimeSync) {
@@ -685,7 +721,7 @@ static void sender_loop() {
}
}
if (g_batch_ack_pending && (now_ms - g_last_batch_send_ms >= BATCH_ACK_TIMEOUT_MS)) {
if (g_batch_ack_pending && (now_ms - g_last_batch_send_ms >= g_batch_ack_timeout_ms)) {
if (g_batch_retry_count < BATCH_MAX_RETRIES) {
g_batch_retry_count++;
serial_debug_printf("ack: timeout batch_id=%u retry=%u", g_inflight_batch_id, g_batch_retry_count);