- Implement periodic WiFi reconnection attempts when stuck in AP mode
- Add WIFI_RECONNECT_INTERVAL_MS config (default 60s) for configurable retry frequency
- Prevent data loss by automatically attempting to switch back to STA mode
- Maintain AP mode for manual configuration if reconnection fails
- Track WiFi config and last reconnection attempt time in shared state
- Add wifi_try_reconnect_sta() and wifi_restore_ap_mode() helper functions
- Log reconnection attempts and results for debugging
Resolve merge conflict in src/main.cpp by accepting the refactored version
from origin. The remote branch includes significant architectural improvements:
- New app context and state machine structures
- Refactored receiver and sender logic
- Library reorganization (dd3_legacy_core, dd3_transport_logic)
- Test framework enhancements
- Code quality improvements
The local WiFi reconnection feature (commit 32cd065) will be
re-integrated if needed in the new architecture.
## 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
- Make include/ the canonical declarations for data_model/html_util/json_codec and convert dd3_legacy_core header copies to thin forwarders.
- Add stable public forwarders for app_context/receiver_pipeline/sender_state_machine and update refactor smoke test to stop using ../../src includes.
- Force-link dd3_legacy_core from setup() to ensure deterministic PlatformIO LDF linking across firmware envs.
- Refresh docs (README, Requirements, docs/TESTS.md) to reflect current module paths and smoke-test include strategy.
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