Complete IoT monitoring platform for Acuvim II power meters via ESP32. Firmware (Phases 1-7): - ESP32-WROVER-B (TTGO T-Call v1.4) with RS485 Modbus RTU - WiFi STA+AP concurrent mode with GSM/GPRS failover - Transport abstraction layer with 4 priority modes - MQTT protocol with 20 commands, LWT, QoS, exponential backoff - SD card offline buffering with JSONL rotation and non-blocking drain - OTA firmware updates with dual partition rollback protection - Watchdog timer, crash loop detection, Acuvim health monitoring - Captive portal provisioning with AP mode Console backend (Phase 8): - .NET 10 minimal API with PostgreSQL + EF Core - JWT authentication, SignalR real-time updates - MQTTnet 5.x bridge service with health monitoring - Device, telemetry, firmware, alert, group management - Rate limiting, security headers, Swagger/OpenAPI Frontend (Phase 9): - React 18 + TypeScript + Vite with Ant Design 5 - ECharts telemetry visualization, TanStack Query - SignalR live updates, device management UI - Dashboard, fleet management, firmware deployment Testing & Production (Phase 10): - 28 firmware unit tests (Modbus, JSON, config, version) - 23 xUnit backend tests (device, telemetry, command, alert) - Docker Compose with nginx, TLS MQTT, PostgreSQL - Production deployment, commissioning, and troubleshooting docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
81 lines
2.0 KiB
C++
81 lines
2.0 KiB
C++
#ifndef OTA_MANAGER_H
|
|
#define OTA_MANAGER_H
|
|
|
|
#include <Arduino.h>
|
|
#include <functional>
|
|
#include "config_manager.h"
|
|
#include "transport_manager.h"
|
|
#include "gsm_manager.h"
|
|
|
|
enum class OtaStatus : uint8_t {
|
|
IDLE,
|
|
CHECKING,
|
|
DOWNLOADING,
|
|
INSTALLING,
|
|
SUCCESS,
|
|
FAILED
|
|
};
|
|
|
|
struct FirmwareInfo {
|
|
String version;
|
|
String url;
|
|
uint32_t size;
|
|
String checksum;
|
|
String releaseNotes;
|
|
bool mandatory;
|
|
};
|
|
|
|
class OtaManager {
|
|
public:
|
|
void begin(ConfigManager& config, TransportManager& transport, GsmManager& gsm);
|
|
void loop();
|
|
|
|
bool checkForUpdate();
|
|
bool startUpdate(const String& url, const String& checksum = "");
|
|
void requestUpdate(const String& url, const String& checksum = "");
|
|
|
|
OtaStatus getStatus() { return _status; }
|
|
uint8_t getProgress() { return _progress; }
|
|
String getStatusMessage() { return _statusMessage; }
|
|
|
|
bool isUpdateAvailable() { return _updateAvailable; }
|
|
const FirmwareInfo& getAvailableUpdate() { return _available; }
|
|
|
|
bool needsValidation();
|
|
bool markValid();
|
|
bool rollback();
|
|
String getRunningPartition();
|
|
|
|
void onProgress(std::function<void(uint8_t)> cb) { _progressCallback = cb; }
|
|
void onComplete(std::function<void(bool, const String&)> cb) { _completeCallback = cb; }
|
|
|
|
private:
|
|
ConfigManager* _config;
|
|
TransportManager* _transport;
|
|
GsmManager* _gsm;
|
|
|
|
OtaStatus _status;
|
|
uint8_t _progress;
|
|
String _statusMessage;
|
|
|
|
bool _updateAvailable;
|
|
FirmwareInfo _available;
|
|
|
|
bool _updateRequested;
|
|
String _pendingUrl;
|
|
String _pendingChecksum;
|
|
|
|
unsigned long _lastCheckMs;
|
|
unsigned long _bootTimeMs;
|
|
bool _firstCheckDone;
|
|
|
|
std::function<void(uint8_t)> _progressCallback;
|
|
std::function<void(bool, const String&)> _completeCallback;
|
|
|
|
bool performUpdate(const String& url);
|
|
bool compareVersions(const String& current, const String& available);
|
|
bool parseUrl(const String& url, String& host, uint16_t& port, String& path);
|
|
};
|
|
|
|
#endif
|