fix: ArduinoOTA init, reporter mutex, BLE lock scope, NVS type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 10:33:23 -07:00
parent 883b72be77
commit 8a00665e4c
5 changed files with 83 additions and 30 deletions

View File

@@ -6,9 +6,15 @@
#include <WiFi.h>
#include <vector>
#include <time.h>
#include <freertos/semphr.h>
static std::vector<CameraHourlyRecord> s_cam_buf;
static std::vector<BLEHourlyRecord> s_ble_buf;
static SemaphoreHandle_t s_buf_mutex = nullptr;
void reporter_init() {
s_buf_mutex = xSemaphoreCreateMutex();
}
// Returns current Unix timestamp (NTP-synced via configTime in main.cpp).
static uint32_t now_ts() {
@@ -86,12 +92,19 @@ static void buf_add_ble(const BLEHourlyRecord& r) {
}
void reporter_submit_camera(const DeviceConfig& cfg, const CameraHourlyRecord& rec) {
if (WiFi.status() != WL_CONNECTED) { buf_add_cam(rec); return; }
if (WiFi.status() != WL_CONNECTED) {
xSemaphoreTake(s_buf_mutex, portMAX_DELAY);
buf_add_cam(rec);
xSemaphoreGive(s_buf_mutex);
return;
}
xSemaphoreTake(s_buf_mutex, portMAX_DELAY);
std::vector<CameraHourlyRecord> batch;
batch.insert(batch.end(), s_cam_buf.begin(), s_cam_buf.end());
batch.push_back(rec);
s_cam_buf.clear();
xSemaphoreGive(s_buf_mutex);
// Cap to MAX_BUFFER: drop oldest to make room for newest
if ((int)batch.size() > REPORTER_MAX_BUFFER) {
@@ -101,17 +114,26 @@ void reporter_submit_camera(const DeviceConfig& cfg, const CameraHourlyRecord& r
String body = build_camera_batch(cfg, batch);
if (!post_json(cfg, "/api/v1/camera/events/batch", body)) {
xSemaphoreTake(s_buf_mutex, portMAX_DELAY);
s_cam_buf = batch; // re-buffer the whole capped batch
xSemaphoreGive(s_buf_mutex);
}
}
void reporter_submit_ble(const DeviceConfig& cfg, const BLEHourlyRecord& rec) {
if (WiFi.status() != WL_CONNECTED) { buf_add_ble(rec); return; }
if (WiFi.status() != WL_CONNECTED) {
xSemaphoreTake(s_buf_mutex, portMAX_DELAY);
buf_add_ble(rec);
xSemaphoreGive(s_buf_mutex);
return;
}
xSemaphoreTake(s_buf_mutex, portMAX_DELAY);
std::vector<BLEHourlyRecord> batch;
batch.insert(batch.end(), s_ble_buf.begin(), s_ble_buf.end());
batch.push_back(rec);
s_ble_buf.clear();
xSemaphoreGive(s_buf_mutex);
// Cap to MAX_BUFFER: drop oldest to make room for newest
if ((int)batch.size() > REPORTER_MAX_BUFFER) {
@@ -121,7 +143,9 @@ void reporter_submit_ble(const DeviceConfig& cfg, const BLEHourlyRecord& rec) {
String body = build_ble_batch(cfg, batch);
if (!post_json(cfg, "/api/v1/events/batch", body)) {
xSemaphoreTake(s_buf_mutex, portMAX_DELAY);
s_ble_buf = batch; // re-buffer the whole capped batch
xSemaphoreGive(s_buf_mutex);
}
}
@@ -137,12 +161,25 @@ void reporter_heartbeat(const DeviceConfig& cfg, uint32_t uptime_s, int wifi_rss
}
void reporter_flush(const DeviceConfig& cfg) {
if (!s_cam_buf.empty()) {
String body = build_camera_batch(cfg, s_cam_buf);
if (post_json(cfg, "/api/v1/camera/events/batch", body)) s_cam_buf.clear();
xSemaphoreTake(s_buf_mutex, portMAX_DELAY);
std::vector<CameraHourlyRecord> cam_snap = s_cam_buf;
std::vector<BLEHourlyRecord> ble_snap = s_ble_buf;
xSemaphoreGive(s_buf_mutex);
if (!cam_snap.empty()) {
String body = build_camera_batch(cfg, cam_snap);
if (post_json(cfg, "/api/v1/camera/events/batch", body)) {
xSemaphoreTake(s_buf_mutex, portMAX_DELAY);
s_cam_buf.clear();
xSemaphoreGive(s_buf_mutex);
}
}
if (!s_ble_buf.empty()) {
String body = build_ble_batch(cfg, s_ble_buf);
if (post_json(cfg, "/api/v1/events/batch", body)) s_ble_buf.clear();
if (!ble_snap.empty()) {
String body = build_ble_batch(cfg, ble_snap);
if (post_json(cfg, "/api/v1/events/batch", body)) {
xSemaphoreTake(s_buf_mutex, portMAX_DELAY);
s_ble_buf.clear();
xSemaphoreGive(s_buf_mutex);
}
}
}