feat: production-ready firmware with BLE memory management, device_id fixes, and docs

- Reduce debug level to 1 (errors only) for production builds
- Replace BLE pause/resume with full deinit/reinit during HTTP uploads (~25KB freed)
- Add 60s boot report delay for fast post-deploy connectivity verification
- Add device_id to BLE batch and heartbeat request bodies
- Correct API host to http:// (plain HTTP, not HTTPS)
- Add HTTP response logging and CV entry/exit serial logging
- Create root README.md with operator setup and architecture overview
- Update design spec: HMAC format, BLE memory approach, request body shapes, reporting intervals

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-16 11:13:50 -07:00
parent 4b671843b3
commit 9d5b588231
8 changed files with 190 additions and 26 deletions

View File

@@ -51,6 +51,7 @@ class ScanCallback : public NimBLEAdvertisedDeviceCallbacks {
std::lock_guard<std::mutex> lock(s_mutex);
auto it = s_seen.find(hash);
if (it == s_seen.end()) {
Serial.printf("[BLE] new device: %s (rssi %d)\n", hash.c_str(), rssi);
s_seen[hash] = {rssi, 1};
} else {
it->second.rssi_sum += rssi;
@@ -75,9 +76,19 @@ void ble_scanner_start() {
s_scan->start(0, nullptr, false); // 0 = continuous
}
void ble_scanner_pause() { if (s_scan) s_scan->stop(); }
void ble_scanner_pause() { if (s_scan) s_scan->stop(); }
void ble_scanner_resume() { if (s_scan) s_scan->start(0, nullptr, false); }
void ble_scanner_deinit() {
if (s_scan) s_scan->stop();
s_scan = nullptr;
NimBLEDevice::deinit(true); // frees NimBLE heap (~25KB)
}
void ble_scanner_reinit() {
ble_scanner_start(); // re-init stack and restart scan
}
BLEHourlyRecord ble_scanner_collect(uint32_t period_start, uint32_t period_end) {
// Swap accumulators under lock — minimise time with lock held
std::map<String, DeviceObs> local_seen;