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>
73 lines
1.7 KiB
C++
73 lines
1.7 KiB
C++
#ifndef TRANSPORT_MANAGER_H
|
|
#define TRANSPORT_MANAGER_H
|
|
|
|
#include <Arduino.h>
|
|
#include <WiFi.h>
|
|
#include <functional>
|
|
#include "wifi_manager.h"
|
|
#include "gsm_manager.h"
|
|
#include "config_manager.h"
|
|
|
|
enum class TransportType {
|
|
NONE,
|
|
WIFI,
|
|
GSM
|
|
};
|
|
|
|
enum class TransportPriority : uint8_t {
|
|
WIFI_PREFERRED = 0,
|
|
GSM_PREFERRED = 1,
|
|
WIFI_ONLY = 2,
|
|
GSM_ONLY = 3
|
|
};
|
|
|
|
class TransportManager {
|
|
public:
|
|
void begin(WifiManager& wifi, GsmManager& gsm,
|
|
ConfigManager& config, WiFiClient* wifiClient);
|
|
void loop();
|
|
|
|
bool isConnected();
|
|
TransportType getActiveTransport() { return _activeTransport; }
|
|
Client& getClient();
|
|
|
|
void setPriority(TransportPriority prio);
|
|
TransportPriority getPriority() { return _priority; }
|
|
|
|
int getSignalStrength();
|
|
const char* getTransportName();
|
|
String getConnectionInfo();
|
|
|
|
void onTransportChange(std::function<void(TransportType)> callback) {
|
|
_onChangeCallback = callback;
|
|
}
|
|
|
|
void forceEvaluate() { _evaluateNow = true; }
|
|
|
|
static const char* transportTypeName(TransportType t);
|
|
|
|
private:
|
|
WifiManager* _wifi;
|
|
GsmManager* _gsm;
|
|
ConfigManager* _config;
|
|
WiFiClient* _wifiClient;
|
|
|
|
TransportType _activeTransport;
|
|
TransportPriority _priority;
|
|
bool _evaluateNow;
|
|
|
|
std::function<void(TransportType)> _onChangeCallback;
|
|
|
|
unsigned long _lastEvaluationMs;
|
|
unsigned long _lastGsmAttemptMs;
|
|
|
|
static const unsigned long EVAL_INTERVAL_MS = 10000;
|
|
static const unsigned long GSM_CONNECT_COOLDOWN_MS = 60000;
|
|
|
|
void evaluateTransport();
|
|
void switchTransport(TransportType newType);
|
|
bool tryGsmConnect();
|
|
};
|
|
|
|
#endif
|