v1.2.0: Firmware refactor to service-oriented architecture + WiFi fixes

Firmware:
- Fixed WiFi reconnection bug after power cycle by adding WiFi.persistent(false)
  and disabling auto-connect/auto-reconnect
- Fixed AP mode not broadcasting by properly handling WIFI_AP_STA mode transitions
- Refactored to service-oriented architecture:
  - device_state: Central state management with event callbacks
  - config_service: NVS persistence (renamed from config_manager)
  - wifi_service: WiFi STA/AP management (extracted from main.cpp)
  - mqtt_service: MQTT client and message routing (extracted from main.cpp)
  - ble_service: BLE GATT services (renamed from ble_services)
  - web_service: HTTP configuration portal (renamed from web_portal)
- main.cpp reduced from ~470 lines to ~60 lines (thin orchestrator)
- Each service is self-contained with setup()/loop() pattern

Backend:
- Added heart rate variation endpoint
- UI improvements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-19 16:49:54 -05:00
parent 9b740ebdd0
commit c95cd33343
22 changed files with 1402 additions and 956 deletions

View File

@@ -0,0 +1,45 @@
#ifndef MQTT_SERVICE_H
#define MQTT_SERVICE_H
#include <Arduino.h>
// ============================================
// MQTT Service
// Manages MQTT connection and message routing
// ============================================
class MqttService {
public:
static MqttService& getInstance();
// Prevent copying
MqttService(const MqttService&) = delete;
MqttService& operator=(const MqttService&) = delete;
// Lifecycle
void setup();
void loop();
// State
bool isConnected() const { return mqttConnected; }
// Publishing
void publishStatus();
void publishValues();
private:
MqttService() = default;
bool mqttConnected = false;
unsigned long lastMqttAttempt = 0;
unsigned long lastStatusReport = 0;
void connectToMQTT();
void handleMessage(char* topic, byte* payload, unsigned int length);
// Static callback wrapper for PubSubClient
static void messageCallback(char* topic, byte* payload, unsigned int length);
};
#define mqttService MqttService::getInstance()
#endif // MQTT_SERVICE_H