Skip to content

Status Updates

Regular health check endpoint for monitoring device connectivity and operational status.

POST /api/v1/device/status
  • Confirm device connectivity and health
  • Report system metrics and resource usage
  • Maintain heartbeat for connection monitoring
  • Check for pending configuration updates
Content-Type: application/json
Authorization: Bearer {device_token}
{
"device_id": "BCGMCU_001",
"timestamp": "2025-01-27T10:30:00.000Z",
"sequence_number": 12345,
"status": {
"bcgmcu_online": true,
"wifi_signal": -45,
"free_memory": 348160,
"uptime": 86400,
"firmware_version": "1.0.0",
"battery_level": null,
"last_data_timestamp": "2025-01-27T10:29:58.000Z"
}
}
FieldTypeRequiredDescription
device_idstringYesUnique device identifier
timestampstringYesUTC ISO8601 timestamp with milliseconds
sequence_numberintegerYesIncrementing sequence number
statusobjectYesDevice status information
FieldTypeRequiredDescription
bcgmcu_onlinebooleanYesBCGMCU module connectivity status
wifi_signalintegerYesWiFi RSSI value in dBm
free_memoryintegerYesAvailable heap memory in bytes
uptimeintegerYesDevice uptime in seconds
firmware_versionstringYesCurrent firmware version
battery_levelintegerNoBattery percentage (null if powered)
last_data_timestampstringYesTimestamp of last successful data transmission
{
"status": "acknowledged",
"server_timestamp": "2025-01-27T10:30:01.000Z",
"sequence_ack": 12345,
"next_status_interval": 300,
"configuration_pending": false
}
FieldTypeDescription
statusstring”acknowledged” or “error”
server_timestampstringServer-side timestamp for synchronization
sequence_ackintegerAcknowledged sequence number
next_status_intervalintegerSeconds until next status update required
configuration_pendingbooleanWhether device should fetch new configuration

When configuration_pending is true:

{
"status": "acknowledged",
"server_timestamp": "2025-01-27T10:30:01.000Z",
"sequence_ack": 12345,
"next_status_interval": 300,
"configuration_pending": true,
"config_version": "v1.2.4"
}

Default status reporting intervals:

Device StateIntervalDescription
Normal Operation300s (5 min)Regular heartbeat
Startup/Registration60sInitial connection phase
Error State30sDuring error recovery
Low Battery60sWhen battery < 20%
Configuration Update10sAfter config change
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <time.h>
class StatusReporter {
private:
unsigned long lastStatusTime = 0;
unsigned long statusInterval = 300000; // 5 minutes default
uint32_t sequenceNumber = 0;
public:
void sendStatusUpdate() {
StaticJsonDocument<512> doc;
// Basic info
doc["device_id"] = getDeviceId();
doc["timestamp"] = getCurrentTimestamp();
doc["sequence_number"] = ++sequenceNumber;
// Status details
JsonObject status = doc.createNestedObject("status");
status["bcgmcu_online"] = bcgmcu.isConnected();
status["wifi_signal"] = WiFi.RSSI();
status["free_memory"] = ESP.getFreeHeap();
status["uptime"] = millis() / 1000;
status["firmware_version"] = FIRMWARE_VERSION;
status["battery_level"] = getBatteryLevel(); // null if not battery powered
status["last_data_timestamp"] = getLastDataTimestamp();
String payload;
serializeJson(doc, payload);
// Send status
HTTPClient https;
https.begin(API_BASE_URL + "/device/status");
https.addHeader("Content-Type", "application/json");
https.addHeader("Authorization", "Bearer " + deviceToken);
int httpCode = https.POST(payload);
if (httpCode == 200) {
handleStatusResponse(https.getString());
} else {
handleStatusError(httpCode);
}
https.end();
}
void handleStatusResponse(String response) {
StaticJsonDocument<256> doc;
deserializeJson(doc, response);
// Update status interval if changed
if (doc.containsKey("next_status_interval")) {
statusInterval = doc["next_status_interval"].as<int>() * 1000;
}
// Check for pending configuration
if (doc["configuration_pending"].as<bool>()) {
fetchConfiguration();
}
// Verify sequence acknowledgment
uint32_t ackSeq = doc["sequence_ack"];
if (ackSeq != sequenceNumber) {
Serial.printf("Sequence mismatch: sent %d, ack %d\n",
sequenceNumber, ackSeq);
}
}
void checkStatus() {
if (millis() - lastStatusTime >= statusInterval) {
sendStatusUpdate();
lastStatusTime = millis();
}
}
};
class AdvancedStatus {
public:
struct SystemMetrics {
float cpu_temperature;
uint32_t task_count;
uint32_t stack_watermark;
uint32_t flash_free;
uint32_t bcgmcu_errors;
uint32_t wifi_reconnects;
};
void collectMetrics(JsonObject& status) {
SystemMetrics metrics = gatherSystemMetrics();
// Core status
status["bcgmcu_online"] = bcgmcu.isConnected();
status["wifi_signal"] = WiFi.RSSI();
status["free_memory"] = ESP.getFreeHeap();
status["uptime"] = millis() / 1000;
// Extended metrics
JsonObject extended = status.createNestedObject("extended");
extended["cpu_temp"] = metrics.cpu_temperature;
extended["task_count"] = metrics.task_count;
extended["stack_watermark"] = metrics.stack_watermark;
extended["flash_free"] = metrics.flash_free;
// Error counters
JsonObject errors = status.createNestedObject("errors");
errors["bcgmcu_errors"] = metrics.bcgmcu_errors;
errors["wifi_reconnects"] = metrics.wifi_reconnects;
errors["failed_transmissions"] = getFailedTransmissions();
// Data statistics
JsonObject data_stats = status.createNestedObject("data_stats");
data_stats["samples_sent"] = getSamplesSent();
data_stats["batches_queued"] = getBatchesQueued();
data_stats["last_success"] = getLastDataTimestamp();
}
};
void handleConnectionLoss() {
// Reduce status interval during issues
if (WiFi.status() != WL_CONNECTED) {
statusInterval = 30000; // 30 seconds
attemptReconnection();
}
if (!bcgmcu.isConnected()) {
// Report BCGMCU offline in next status
bcgmcuOnline = false;
statusInterval = 60000; // 1 minute
}
}
class OfflineStatusQueue {
private:
struct StatusEntry {
uint32_t timestamp;
uint32_t sequence;
String statusJson;
};
std::vector<StatusEntry> queue;
const size_t MAX_QUEUE = 100;
public:
void queueStatus(String statusJson) {
if (queue.size() >= MAX_QUEUE) {
queue.erase(queue.begin()); // Remove oldest
}
StatusEntry entry;
entry.timestamp = time(nullptr);
entry.sequence = getNextSequence();
entry.statusJson = statusJson;
queue.push_back(entry);
}
void flushQueue() {
for (auto& entry : queue) {
if (sendStatus(entry.statusJson)) {
// Mark as sent
} else {
break; // Stop if sending fails
}
}
queue.clear();
}
};
  1. Regular Heartbeat: Always maintain minimum 5-minute status interval
  2. Sequence Tracking: Use sequence numbers to detect missed updates
  3. Timestamp Accuracy: Sync with NTP for accurate timestamps
  4. Resource Monitoring: Track memory and CPU usage trends
  5. Error Reporting: Include error counters in status updates
  6. Adaptive Intervals: Reduce interval during issues or errors
  7. Configuration Checks: Always process configuration_pending flag

Status updates enable dashboard features:

  • Device Health Map: Real-time status visualization
  • Alert Generation: Automatic alerts for offline devices
  • Resource Tracking: Memory and CPU usage trends
  • Network Quality: WiFi signal strength monitoring
  • Uptime Statistics: Device reliability metrics