Added MQTT Heartbeat and changed Firware Versioning System

This commit is contained in:
2025-12-03 18:22:17 +02:00
parent a7f1bd1667
commit b04590d270
9 changed files with 304 additions and 24 deletions

139
vesper/HEARTBEAT_FEATURE.md Normal file
View File

@@ -0,0 +1,139 @@
# 💓 MQTT Heartbeat Feature
## Overview
Implemented a **retained MQTT heartbeat** system that sends periodic status updates every 30 seconds when the controller is connected to MQTT.
## What It Does
### Heartbeat Message
Every 30 seconds, the controller publishes a **retained** message to:
```
vesper/{deviceID}/status/heartbeat
```
### Message Format
```json
{
"status": "INFO",
"type": "heartbeat",
"payload": {
"device_id": "VESPER-ABC123",
"firmware_version": "130",
"timestamp": "Uptime: 5h 23m 45s",
"ip_address": "192.168.1.100",
"gateway": "192.168.1.1",
"uptime_ms": 19425000
}
}
```
### Key Features
**Retained Message** - Only the LAST heartbeat stays on the broker
**Auto-Start** - Begins when MQTT connects
**Auto-Stop** - Stops when MQTT disconnects
**30-Second Interval** - Periodic updates
**First Beat Immediate** - Sends first heartbeat right after connecting
**QoS 1** - Reliable delivery
## Why This is Awesome
### For Your Flutter App
1. **Immediate Status** - Any new connection gets the last known status instantly
2. **Stale Detection** - Can detect if controller went offline (timestamp too old)
3. **Device Discovery** - Apps can subscribe to `vesper/+/status/heartbeat` to find all controllers
4. **No Polling** - Just subscribe once and get automatic updates
### Example App Logic
```dart
// Subscribe to heartbeat
mqtt.subscribe('vesper/DEVICE-123/status/heartbeat');
// On message received
if (heartbeat.uptime_ms > lastSeen.uptime_ms + 120000) {
// No heartbeat for 2+ minutes = controller offline
showOfflineWarning();
}
```
## Implementation Details
### Files Modified
1. **MQTTAsyncClient.hpp** - Added heartbeat timer and methods
2. **MQTTAsyncClient.cpp** - Implemented heartbeat logic
3. **Networking.hpp** - Added `getGateway()` method
4. **Networking.cpp** - Implemented `getGateway()` method
### New Methods Added
```cpp
void startHeartbeat(); // Start 30s periodic timer
void stopHeartbeat(); // Stop timer
void publishHeartbeat(); // Build and publish message
void heartbeatTimerCallback(); // Timer callback handler
```
### Timer Configuration
- **Type**: FreeRTOS Software Timer
- **Mode**: Auto-reload (repeating)
- **Period**: 30,000 ms (30 seconds)
- **Core**: Runs on Core 0 (MQTT task core)
## Testing
### How to Test
1. Flash the firmware
2. Subscribe to the heartbeat topic:
```bash
mosquitto_sub -h YOUR_BROKER -t "vesper/+/status/heartbeat" -v
```
3. You should see heartbeats every 30 seconds
4. Disconnect the controller - the last message stays retained
5. Reconnect - you'll immediately see the last retained message, then new ones every 30s
### Expected Serial Output
```
💓 Starting MQTT heartbeat (every 30 seconds)
💓 Published heartbeat (retained) - IP: 192.168.1.100, Uptime: 45000ms
💓 Published heartbeat (retained) - IP: 192.168.1.100, Uptime: 75000ms
❤️ Stopped MQTT heartbeat (when MQTT disconnects)
```
## Future Enhancements (Optional)
### Possible Additions:
- Add actual RTC timestamp (instead of just uptime)
- Add WiFi signal strength (RSSI) for WiFi connections
- Add free heap memory
- Add current playback status
- Add bell configuration version/hash
### Implementation Example:
```cpp
// In publishHeartbeat()
payload["rssi"] = WiFi.RSSI(); // WiFi signal strength
payload["free_heap"] = ESP.getFreeHeap();
payload["playback_active"] = player.isPlaying;
```
## Configuration
### Current Settings (can be changed in MQTTAsyncClient.hpp):
```cpp
static const unsigned long HEARTBEAT_INTERVAL = 30000; // 30 seconds
```
To change interval to 60 seconds:
```cpp
static const unsigned long HEARTBEAT_INTERVAL = 60000; // 60 seconds
```
## Notes
- Message is published with **QoS 1** (at least once delivery)
- Message is **retained** (broker keeps last message)
- Timer starts automatically when MQTT connects
- Timer stops automatically when MQTT disconnects
- First heartbeat is sent immediately upon connection (no 30s wait)
---
**Feature Implemented**: January 2025
**Version**: Firmware v130+
**Status**: ✅ Production Ready