## Bug Fixes
- Fix integer overflow potential in history bin allocation (web_server.cpp)
Using uint64_t for intermediate multiplication prevents overflow with different constants
- Prevent data loss during WiFi failures (main.cpp)
Device now automatically attempts WiFi reconnection every 30 seconds when in AP mode
Exits AP mode and resumes MQTT transmission as soon as WiFi becomes available
Data collection and SD logging continue regardless of connectivity
## New Features
- Add standalone MQTT data republisher for lost data recovery
- Command-line tool (republish_mqtt.py) with interactive and scripting modes
- GUI tool (republish_mqtt_gui.py) for user-friendly recovery
- Rate-limited publishing (5 msg/sec default, configurable 1-100)
- Manual time range selection or auto-detect missing data via InfluxDB
- Cross-platform support (Windows, macOS, Linux)
- Converts SD card CSV exports back to MQTT format
## Documentation
- Add comprehensive code review (CODE_REVIEW.md)
- 16 detailed security and quality assessments
- Identifies critical HTTPS/auth gaps, medium-priority overflow issues
- Confirms absence of buffer overflows and unsafe string functions
- Grade: B+ with areas for improvement
- Add republisher documentation (REPUBLISH_README.md, REPUBLISH_GUI_README.md)
- Installation and usage instructions
- Example commands and scenarios
- Troubleshooting guide
- Performance characteristics
## Dependencies
- Add requirements_republish.txt
- paho-mqtt>=1.6.1
- influxdb-client>=1.18.0
## Impact
- Eliminates data loss scenario where unreliable WiFi leaves device stuck in AP mode
- Provides recovery mechanism for any historical data missed during outages
- Improves code safety with explicit overflow-resistant arithmetic
- Increases operational visibility with comprehensive code review
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
- Add BATTERY_CAL config and debug logging for raw ADC samples
- Use LiPo voltage curve (4.2V full, 2.9V empty) for % mapping
- Document battery calibration, curve, and debug output in README
- 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