BACKWARD-INCOMPATIBLE: MeterBatch schema bumped to v2 with err_rx_reject.
- Track and log RX reject reasons (CRC/protocol/role/payload/length/id/batch)
- Include rx_reject in sender telemetry JSON and receiver web UI
- Add lora_receive reject reason logging under SERIAL_DEBUG_MODE
- Add TimeSync fault code and labels in UI/SD/web docs
- Trigger receiver beacon bursts on sender drift, but keep errors sender-local
- Sender flags TimeSync only after TIME_SYNC_ERROR_TIMEOUT_MS
- Track last OLED activity to avoid double timeout; keep power gating on transitions
- Copy TZ before setenv() in timegm_fallback to avoid invalid pointer reuse
- Add BATTERY_SAMPLE_INTERVAL_MS and only refresh cache at batch start when due
- Keep battery sampling to a single ADC read (Arduino core lacks explicit ADC power gating)
- Add lora_receive_continuous() helper and use it after init and TX (ACK/time sync)
- Ensure receiver returns to RX immediately after lora_send
- Document continuous RX behavior in README
- Add RX state machine with frame buffer, timeouts, and debug counters
- Expose meter_poll_frame/meter_parse_frame and reuse existing OBIS parsing
- Use cached last-valid frame at 1 Hz sampling to avoid blocking
- Document non-blocking meter handling in README
- Add LoRa idle/sleep/receive-window helpers and use short RX windows for ACK/time sync
- Schedule sender time-sync windows (fast/slow) and track RX vs sleep time in debug
- Lower sender power (80 MHz CPU, WiFi/BT off, reduced ADC sampling, unused pins pulldown)
- Make SERIAL_DEBUG_MODE a build flag, add prod envs with debug off, and document changes
- Add SD history chart + download listing to web UI
- Use HSPI for SD and fix SD pin mapping
- Swap role/OLED control pins and update role detection
- Update README pin mapping and SD/history docs
- Add optional microSD CSV logging per sender/day on receiver
- Wire logger into receiver packet handling
- Document new batch header fields, build envs, and SD logging
- Make sender links open in a new tab