@alteriom/painlessmesh 1.7.6 → 1.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +177 -0
  2. package/README.md +96 -14
  3. package/RELEASE_GUIDE.md +36 -0
  4. package/docs/API_DESIGN_GUIDELINES.md +414 -0
  5. package/docs/BOOLEAN_NAMING_CONVENTION.md +235 -0
  6. package/docs/MQTT_BRIDGE_COMMANDS.md +10 -10
  7. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +1 -1
  8. package/docs/MQTT_SCHEMA_COMPLIANCE.md +57 -2
  9. package/docs/PHASE1_GUIDE.md +1 -1
  10. package/docs/alteriom/overview.md +25 -2
  11. package/docs/architecture/plugin-system.md +1 -1
  12. package/docs/archive/RELEASE_SUMMARY.md +1 -1
  13. package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +389 -0
  14. package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +391 -0
  15. package/docs/v1.7.7_MQTT_IMPROVEMENTS.md +794 -0
  16. package/docs/wiki/API-Reference.md +2 -2
  17. package/docs/wiki/Complete-Documentation.md +1 -1
  18. package/examples/alteriom/README.md +150 -4
  19. package/examples/alteriom/alteriom.ino +1 -1
  20. package/examples/alteriom/alteriom_sensor_package.hpp +914 -4
  21. package/examples/alteriomImproved/alteriom_sensor_package.hpp +1 -1
  22. package/examples/alteriomImproved/improved_sensor_node.ino +1 -1
  23. package/examples/alteriomMetricsHealth/alteriom_sensor_package.hpp +796 -0
  24. package/examples/alteriomMetricsHealth/metrics_health_node.ino +418 -0
  25. package/examples/alteriomMetricsHealth/platformio.ini +26 -0
  26. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +1 -1
  27. package/examples/alteriomPhase1/phase1_features.ino +2 -2
  28. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +1 -1
  29. package/examples/alteriomSensorNode/alteriom_sensor_node.ino +1 -1
  30. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +1 -1
  31. package/examples/bridge/enhanced_mqtt_bridge.hpp +610 -0
  32. package/examples/bridge/enhanced_mqtt_bridge_example.ino +226 -0
  33. package/examples/meshCommandNode/alteriom_sensor_package.hpp +1 -1
  34. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +1 -1
  35. package/examples/mqttTopologyTest/mqttTopologyTest.ino +5 -1
  36. package/library.json +1 -1
  37. package/library.properties +1 -1
  38. package/package.json +2 -2
@@ -0,0 +1,794 @@
1
+ # Version 1.7.7 - Enhanced MQTT Communication for Metrics & Health Monitoring
2
+
3
+ ## Overview
4
+
5
+ Version 1.7.7 introduces two new specialized packages designed to enhance MQTT communication efficiency for monitoring mesh networks. These packages provide comprehensive visibility into system performance, proactive problem detection, and predictive maintenance capabilities.
6
+
7
+ ## New Package Types
8
+
9
+ ### MetricsPackage (Type 204)
10
+
11
+ A comprehensive performance metrics package designed for real-time dashboards, capacity planning, and network optimization.
12
+
13
+ #### Purpose
14
+
15
+ - **Real-time Monitoring** - Track system performance in real-time
16
+ - **Capacity Planning** - Identify bottlenecks and plan upgrades
17
+ - **Performance Optimization** - Analyze and improve system efficiency
18
+ - **Troubleshooting** - Diagnose performance issues quickly
19
+
20
+ #### Key Metrics Categories
21
+
22
+ **CPU and Processing:**
23
+ - `cpuUsage` (uint8_t) - CPU usage percentage (0-100)
24
+ - `loopIterations` (uint32_t) - Loop iterations per second
25
+ - `taskQueueSize` (uint16_t) - Number of pending tasks
26
+
27
+ **Memory Metrics:**
28
+ - `freeHeap` (uint32_t) - Current free heap memory in bytes
29
+ - `minFreeHeap` (uint32_t) - Minimum free heap since boot
30
+ - `heapFragmentation` (uint32_t) - Heap fragmentation percentage
31
+ - `maxAllocHeap` (uint32_t) - Largest allocatable block
32
+
33
+ **Network Performance:**
34
+ - `bytesReceived` (uint32_t) - Total bytes received
35
+ - `bytesSent` (uint32_t) - Total bytes sent
36
+ - `packetsReceived` (uint16_t) - Total packets received
37
+ - `packetsSent` (uint16_t) - Total packets sent
38
+ - `packetsDropped` (uint16_t) - Packets dropped
39
+ - `currentThroughput` (uint16_t) - Current throughput in bytes/sec
40
+
41
+ **Timing and Latency:**
42
+ - `avgResponseTime` (uint32_t) - Average response time in microseconds
43
+ - `maxResponseTime` (uint32_t) - Maximum response time in microseconds
44
+ - `avgMeshLatency` (uint16_t) - Average mesh latency in milliseconds
45
+
46
+ **Connection Quality:**
47
+ - `connectionQuality` (uint8_t) - Overall connection quality score (0-100)
48
+ - `wifiRSSI` (int8_t) - WiFi RSSI in dBm
49
+
50
+ **Metadata:**
51
+ - `collectionTimestamp` (uint32_t) - When metrics were collected
52
+ - `collectionInterval` (uint32_t) - Interval between collections in ms
53
+
54
+ #### Example Usage
55
+
56
+ ```cpp
57
+ #include "alteriom_sensor_package.hpp"
58
+ using namespace alteriom;
59
+
60
+ void collectAndSendMetrics() {
61
+ MetricsPackage metrics;
62
+ metrics.from = mesh.getNodeId();
63
+
64
+ // Collect CPU metrics
65
+ metrics.cpuUsage = calculateCPUUsage();
66
+ metrics.loopIterations = getLoopsPerSecond();
67
+ metrics.taskQueueSize = scheduler.size();
68
+
69
+ // Collect memory metrics
70
+ metrics.freeHeap = ESP.getFreeHeap();
71
+ metrics.minFreeHeap = getMinHeapSinceBoot();
72
+ #ifdef ESP32
73
+ metrics.maxAllocHeap = ESP.getMaxAllocHeap();
74
+ #else
75
+ metrics.heapFragmentation = ESP.getHeapFragmentation();
76
+ metrics.maxAllocHeap = ESP.getMaxFreeBlockSize();
77
+ #endif
78
+
79
+ // Collect network metrics
80
+ metrics.bytesReceived = getTotalBytesRx();
81
+ metrics.bytesSent = getTotalBytesTx();
82
+ metrics.currentThroughput = calculateThroughput();
83
+
84
+ // Connection quality
85
+ metrics.connectionQuality = calculateConnectionQuality();
86
+ metrics.wifiRSSI = WiFi.RSSI();
87
+
88
+ // Metadata
89
+ metrics.collectionTimestamp = mesh.getNodeTime();
90
+ metrics.collectionInterval = 30000; // 30 seconds
91
+
92
+ // Send metrics
93
+ mesh.sendBroadcast(metrics.toJsonString());
94
+ }
95
+ ```
96
+
97
+ #### MQTT Integration
98
+
99
+ When using with the MQTT bridge, metrics are published to:
100
+ - `mesh/metrics/{node_id}` - Per-node metrics
101
+ - `mesh/metrics/aggregated` - Aggregated mesh-wide metrics
102
+
103
+ #### Dashboard Integration
104
+
105
+ **Grafana:**
106
+ ```json
107
+ {
108
+ "cpu_usage": "${cpuUsage}",
109
+ "free_heap": "${freeHeap}",
110
+ "throughput": "${currentThroughput}",
111
+ "rssi": "${wifiRSSI}",
112
+ "quality": "${connectionQuality}"
113
+ }
114
+ ```
115
+
116
+ **InfluxDB Line Protocol:**
117
+ ```
118
+ metrics,node_id=12345 cpu=${cpuUsage},heap=${freeHeap},throughput=${currentThroughput} ${timestamp}
119
+ ```
120
+
121
+ ### HealthCheckPackage (Type 605)
122
+
123
+ A proactive health monitoring package designed for early problem detection, predictive maintenance, and automated alerting.
124
+
125
+ #### Purpose
126
+
127
+ - **Proactive Detection** - Identify problems before they cause failures
128
+ - **Predictive Maintenance** - Estimate time to failure and plan maintenance
129
+ - **Automated Alerting** - Trigger alerts based on health thresholds
130
+ - **Root Cause Analysis** - Provide detailed health indicators for troubleshooting
131
+
132
+ #### Health Status Levels
133
+
134
+ - **2 (Healthy)** - All systems operating normally
135
+ - **1 (Warning)** - Some issues detected, monitoring required
136
+ - **0 (Critical)** - Immediate attention required
137
+
138
+ #### Problem Flags (Bit Flags)
139
+
140
+ | Flag | Value | Description |
141
+ |------|-------|-------------|
142
+ | Low Memory | 0x0001 | Free memory below threshold |
143
+ | High CPU | 0x0002 | CPU usage above threshold |
144
+ | Connection Instability | 0x0004 | Frequent reconnections |
145
+ | High Packet Loss | 0x0008 | Packet loss above threshold |
146
+ | Network Congestion | 0x0010 | Network congestion detected |
147
+ | Low Battery | 0x0020 | Battery level critical |
148
+ | Thermal Warning | 0x0040 | Temperature above safe limit |
149
+ | Mesh Partition | 0x0080 | Mesh network partitioned |
150
+ | OTA in Progress | 0x0100 | Firmware update active |
151
+ | Configuration Error | 0x0200 | Configuration issue detected |
152
+
153
+ #### Health Scores (0-100)
154
+
155
+ Each component (memory, network, performance) has a health score:
156
+ - **90-100** - Excellent
157
+ - **70-89** - Good
158
+ - **50-69** - Fair
159
+ - **30-49** - Poor
160
+ - **0-29** - Critical
161
+
162
+ #### Key Fields
163
+
164
+ **Overall Health:**
165
+ - `healthStatus` (uint8_t) - Overall status (0-2)
166
+ - `problemFlags` (uint16_t) - Bit flags for specific problems
167
+
168
+ **Component Health:**
169
+ - `memoryHealth` (uint8_t) - Memory health score (0-100)
170
+ - `memoryTrend` (uint32_t) - Memory loss rate in bytes/hour
171
+ - `networkHealth` (uint8_t) - Network health score (0-100)
172
+ - `packetLossPercent` (uint8_t) - Current packet loss percentage
173
+ - `reconnectionCount` (uint8_t) - Reconnections in last hour
174
+ - `performanceHealth` (uint8_t) - Performance health score (0-100)
175
+ - `missedDeadlines` (uint32_t) - Missed task deadlines
176
+ - `maxLoopTime` (uint16_t) - Maximum loop execution time in ms
177
+
178
+ **Environmental:**
179
+ - `temperature` (int8_t) - Device temperature in Celsius
180
+ - `temperatureHealth` (uint8_t) - Temperature health score
181
+
182
+ **Stability:**
183
+ - `uptime` (uint32_t) - Uptime in seconds
184
+ - `crashCount` (uint16_t) - Crash/restart count
185
+ - `lastRebootReason` (uint32_t) - Last reboot reason code
186
+
187
+ **Predictive:**
188
+ - `estimatedTimeToFailure` (uint16_t) - Estimated hours until failure (0=unknown)
189
+ - `recommendations` (TSTRING) - Recommended actions
190
+
191
+ #### Example Usage
192
+
193
+ ```cpp
194
+ void performHealthCheck() {
195
+ HealthCheckPackage health;
196
+ health.from = mesh.getNodeId();
197
+
198
+ // Calculate component health scores
199
+ uint8_t memHealth = calculateMemoryHealth();
200
+ uint8_t netHealth = calculateNetworkHealth();
201
+ uint8_t perfHealth = calculatePerformanceHealth();
202
+
203
+ // Determine overall health status
204
+ if (memHealth < 30 || netHealth < 30 || perfHealth < 30) {
205
+ health.healthStatus = 0; // Critical
206
+ } else if (memHealth < 60 || netHealth < 60 || perfHealth < 60) {
207
+ health.healthStatus = 1; // Warning
208
+ } else {
209
+ health.healthStatus = 2; // Healthy
210
+ }
211
+
212
+ // Set problem flags
213
+ health.problemFlags = 0;
214
+ if (memHealth < 60) health.problemFlags |= 0x0001;
215
+ if (perfHealth < 60) health.problemFlags |= 0x0002;
216
+ if (netHealth < 60) health.problemFlags |= 0x0004;
217
+
218
+ // Component health
219
+ health.memoryHealth = memHealth;
220
+ health.memoryTrend = calculateMemoryTrend();
221
+ health.networkHealth = netHealth;
222
+ health.packetLossPercent = getPacketLossPercent();
223
+ health.performanceHealth = perfHealth;
224
+
225
+ // Predictive indicators
226
+ if (health.memoryTrend > 0) {
227
+ uint32_t freeHeap = ESP.getFreeHeap();
228
+ health.estimatedTimeToFailure = freeHeap / health.memoryTrend;
229
+ }
230
+
231
+ // Recommendations
232
+ if (health.healthStatus == 0) {
233
+ health.recommendations = "CRITICAL: Immediate attention required";
234
+ } else if (health.healthStatus == 1) {
235
+ if (memHealth < 60) {
236
+ health.recommendations = "Increase memory allocation";
237
+ } else if (netHealth < 60) {
238
+ health.recommendations = "Check network connections";
239
+ }
240
+ } else {
241
+ health.recommendations = "System operating normally";
242
+ }
243
+
244
+ // Send health check
245
+ mesh.sendBroadcast(health.toJsonString());
246
+ }
247
+ ```
248
+
249
+ #### Alert Integration
250
+
251
+ **Home Assistant:**
252
+ ```yaml
253
+ - platform: mqtt
254
+ name: "Mesh Node Health"
255
+ state_topic: "mesh/health/12345"
256
+ value_template: "{{ value_json.healthStatus }}"
257
+ json_attributes_topic: "mesh/health/12345"
258
+ json_attributes_template: "{{ value_json | tojson }}"
259
+ ```
260
+
261
+ **Alerting Rules:**
262
+ ```yaml
263
+ alerts:
264
+ - name: critical_health
265
+ condition: healthStatus == 0
266
+ action: send_notification
267
+ - name: memory_warning
268
+ condition: memoryHealth < 60
269
+ action: log_warning
270
+ - name: predicted_failure
271
+ condition: estimatedTimeToFailure < 24
272
+ action: schedule_maintenance
273
+ ```
274
+
275
+ ## Collection Intervals
276
+
277
+ ### Recommended Intervals
278
+
279
+ | Package Type | Interval | Use Case |
280
+ |--------------|----------|----------|
281
+ | MetricsPackage | 30-60s | Normal monitoring |
282
+ | MetricsPackage | 10-30s | Active troubleshooting |
283
+ | MetricsPackage | 5-10s | Critical performance analysis |
284
+ | HealthCheckPackage | 60s | Normal health monitoring |
285
+ | HealthCheckPackage | 30s | Warning state monitoring |
286
+ | HealthCheckPackage | 10s | Critical state monitoring |
287
+
288
+ ### Configurable Collection
289
+
290
+ ```cpp
291
+ // In setup()
292
+ #define METRICS_INTERVAL 30000 // 30 seconds
293
+ #define HEALTH_INTERVAL 60000 // 60 seconds
294
+
295
+ Task taskMetrics(METRICS_INTERVAL, TASK_FOREVER, &sendMetrics);
296
+ Task taskHealth(HEALTH_INTERVAL, TASK_FOREVER, &sendHealthCheck);
297
+
298
+ userScheduler.addTask(taskMetrics);
299
+ userScheduler.addTask(taskHealth);
300
+
301
+ taskMetrics.enable();
302
+ taskHealth.enable();
303
+
304
+ // Dynamic adjustment based on health status
305
+ void adjustCollectionIntervals(uint8_t healthStatus) {
306
+ if (healthStatus == 0) { // Critical
307
+ taskMetrics.setInterval(10000); // 10 seconds
308
+ taskHealth.setInterval(10000);
309
+ } else if (healthStatus == 1) { // Warning
310
+ taskMetrics.setInterval(20000); // 20 seconds
311
+ taskHealth.setInterval(30000);
312
+ } else { // Healthy
313
+ taskMetrics.setInterval(60000); // 60 seconds
314
+ taskHealth.setInterval(60000);
315
+ }
316
+ }
317
+ ```
318
+
319
+ ## MQTT Bridge Integration
320
+
321
+ ### Publishing Topics
322
+
323
+ #### Per-Node Topics
324
+ - `mesh/metrics/{node_id}` - Individual node metrics
325
+ - `mesh/health/{node_id}` - Individual node health checks
326
+
327
+ #### Aggregated Topics
328
+ - `mesh/metrics/aggregated` - Mesh-wide aggregated metrics
329
+ - `mesh/health/summary` - Overall mesh health summary
330
+ - `mesh/alerts` - Active alerts across the mesh
331
+
332
+ ### Message Format (Updated for @alteriom/mqtt-schema v0.7.2+)
333
+
334
+ Packages now include the `message_type` field for 90% faster message classification:
335
+
336
+ ```json
337
+ {
338
+ "schema_version": 1,
339
+ "device_id": "ALT-12345",
340
+ "timestamp": "2025-10-23T21:30:00Z",
341
+ "type": 204,
342
+ "message_type": 204,
343
+ "from": 12345,
344
+ "cpuUsage": 45,
345
+ "freeHeap": 100000,
346
+ "currentThroughput": 8192,
347
+ "connectionQuality": 85,
348
+ "wifiRSSI": -55,
349
+ ...
350
+ }
351
+ ```
352
+
353
+ **Message Type Codes (mqtt-schema v0.7.2+):**
354
+
355
+ For performance optimization and standardized routing, all Alteriom packages include the `message_type` field:
356
+
357
+ | Code | Constant | Message Type | Category | Description | PainlessMesh Package |
358
+ |------|----------|--------------|----------|-------------|---------------------|
359
+ | 200 | SENSOR_DATA | sensor_data | telemetry | Sensor telemetry readings | SensorPackage |
360
+ | 202 | SENSOR_STATUS | sensor_status | telemetry | Sensor status change | StatusPackage |
361
+ | 204 | SENSOR_METRICS | sensor_metrics | telemetry | Sensor health and performance metrics | MetricsPackage |
362
+ | 400 | COMMAND | command | control | Device control command | CommandPackage |
363
+ | 600 | MESH_NODE_LIST | mesh_node_list | mesh | Mesh node inventory | MeshNodeListPackage |
364
+ | 601 | MESH_TOPOLOGY | mesh_topology | mesh | Mesh network topology | MeshTopologyPackage |
365
+ | 602 | MESH_ALERT | mesh_alert | mesh | Mesh network alert | MeshAlertPackage |
366
+ | 603 | MESH_BRIDGE | mesh_bridge | mesh | Mesh protocol bridge | MeshBridgePackage |
367
+ | 604 | MESH_STATUS | mesh_status | mesh | Mesh network health status | EnhancedStatusPackage |
368
+ | 605 | MESH_METRICS | mesh_metrics | mesh | Mesh network performance metrics | HealthCheckPackage |
369
+
370
+ **Key Points:**
371
+ - The `message_type` field enables 90% faster message classification compared to parsing JSON
372
+ - All Alteriom packages align with @alteriom/mqtt-schema v0.7.2+ standards
373
+ - Message type codes are consistent across MQTT bridge, gateway, and mesh nodes
374
+
375
+ ## Implementation Guide
376
+
377
+ ### Basic Implementation
378
+
379
+ See `examples/alteriom/metrics_health_node.ino` for a complete working example.
380
+
381
+ ### Integration with Existing Code
382
+
383
+ ```cpp
384
+ #include "alteriom_sensor_package.hpp"
385
+ using namespace alteriom;
386
+
387
+ // Add to your existing mesh node
388
+ void setup() {
389
+ // ... existing mesh setup ...
390
+
391
+ // Add metrics collection task
392
+ userScheduler.addTask(Task(30000, TASK_FOREVER, []() {
393
+ MetricsPackage metrics;
394
+ // ... populate metrics ...
395
+ mesh.sendBroadcast(metrics.toJsonString());
396
+ }));
397
+
398
+ // Add health check task
399
+ userScheduler.addTask(Task(60000, TASK_FOREVER, []() {
400
+ HealthCheckPackage health;
401
+ // ... populate health data ...
402
+ mesh.sendBroadcast(health.toJsonString());
403
+ }));
404
+ }
405
+ ```
406
+
407
+ ### Gateway Bridge Integration
408
+
409
+ ```cpp
410
+ // In MQTT bridge receivedCallback
411
+ void receivedCallback(uint32_t from, String& msg) {
412
+ DynamicJsonDocument doc(2048);
413
+ deserializeJson(doc, msg);
414
+
415
+ uint8_t msgType = doc["type"];
416
+
417
+ switch(msgType) {
418
+ case 204: // MetricsPackage
419
+ publishMetricsToMQTT(from, doc);
420
+ break;
421
+ case 605: // HealthCheckPackage (MESH_METRICS)
422
+ publishHealthToMQTT(from, doc);
423
+ checkForAlerts(doc);
424
+ break;
425
+ }
426
+ }
427
+
428
+ void publishMetricsToMQTT(uint32_t from, JsonDocument& doc) {
429
+ String topic = "mesh/metrics/" + String(from);
430
+ String payload;
431
+ serializeJson(doc, payload);
432
+ mqttClient.publish(topic.c_str(), payload.c_str());
433
+ }
434
+
435
+ void checkForAlerts(JsonDocument& doc) {
436
+ uint8_t healthStatus = doc["health"];
437
+ uint16_t problemFlags = doc["problems"];
438
+
439
+ if (healthStatus == 0) {
440
+ String alertTopic = "mesh/alerts/critical";
441
+ String alertMsg = "Critical health on node " + String(doc["from"].as<uint32_t>());
442
+ mqttClient.publish(alertTopic.c_str(), alertMsg.c_str());
443
+ }
444
+ }
445
+ ```
446
+
447
+ ## Performance Considerations
448
+
449
+ ### Memory Usage
450
+
451
+ - **MetricsPackage**: ~200 bytes per message
452
+ - **HealthCheckPackage**: ~250 bytes per message (including recommendations string)
453
+ - **Total overhead**: <1KB for both packages with reasonable collection intervals
454
+
455
+ ### Network Bandwidth
456
+
457
+ With 10 nodes and recommended intervals:
458
+ - **Metrics (30s)**: 10 nodes × 200 bytes / 30s = ~67 bytes/sec
459
+ - **Health (60s)**: 10 nodes × 250 bytes / 60s = ~42 bytes/sec
460
+ - **Total**: ~109 bytes/sec = minimal overhead
461
+
462
+ ### Optimization Tips
463
+
464
+ 1. **Adjust intervals based on load** - Increase intervals during normal operation
465
+ 2. **Use selective reporting** - Only send metrics that changed significantly
466
+ 3. **Aggregate at gateway** - Combine multiple node metrics before MQTT publish
467
+ 4. **Compress recommendations** - Use short, standardized recommendation codes
468
+ 5. **Throttle during congestion** - Reduce collection frequency when network is busy
469
+
470
+ ## Testing
471
+
472
+ ### Unit Tests
473
+
474
+ Run the comprehensive test suite:
475
+ ```bash
476
+ ./bin/catch_metrics_health_packages
477
+ ```
478
+
479
+ Tests validate:
480
+ - Serialization/deserialization
481
+ - Field preservation
482
+ - Edge cases (min/max values)
483
+ - Problem flag handling
484
+ - Health status levels
485
+ - Integration with painlessMesh plugin system
486
+
487
+ ### Integration Testing
488
+
489
+ ```cpp
490
+ // Test metrics collection
491
+ void testMetrics() {
492
+ MetricsPackage metrics;
493
+ metrics.from = 12345;
494
+ metrics.cpuUsage = 45;
495
+ metrics.freeHeap = 100000;
496
+
497
+ auto var = protocol::Variant(&metrics);
498
+ auto metrics2 = var.to<MetricsPackage>();
499
+
500
+ assert(metrics2.cpuUsage == 45);
501
+ assert(metrics2.freeHeap == 100000);
502
+ }
503
+
504
+ // Test health monitoring
505
+ void testHealth() {
506
+ HealthCheckPackage health;
507
+ health.from = 12345;
508
+ health.healthStatus = 1;
509
+ health.problemFlags = 0x0001;
510
+
511
+ auto var = protocol::Variant(&health);
512
+ auto health2 = var.to<HealthCheckPackage>();
513
+
514
+ assert(health2.healthStatus == 1);
515
+ assert(health2.problemFlags == 0x0001);
516
+ }
517
+ ```
518
+
519
+ ## Migration from Previous Versions
520
+
521
+ ### From v1.7.6
522
+
523
+ No breaking changes. Simply add the new packages to your code:
524
+
525
+ ```cpp
526
+ // Add new includes
527
+ #include "alteriom_sensor_package.hpp"
528
+ using namespace alteriom;
529
+
530
+ // Add new collection tasks
531
+ // ... see examples above ...
532
+ ```
533
+
534
+ ### Backward Compatibility
535
+
536
+ - All existing packages (200-203) continue to work unchanged
537
+ - New packages (204, 604, 605) are optional additions
538
+ - No changes required to existing code
539
+ - Can be adopted incrementally
540
+
541
+ ## Best Practices
542
+
543
+ 1. **Start with conservative intervals** - Begin with 60s intervals and adjust based on needs
544
+ 2. **Monitor memory usage** - Watch heap fragmentation when enabling new packages
545
+ 3. **Implement health-based throttling** - Reduce collection frequency when unhealthy
546
+ 4. **Use problem flags effectively** - Check specific flags rather than just status
547
+ 5. **Act on recommendations** - Implement automated responses to common recommendations
548
+ 6. **Set up alerting** - Configure alerts for critical health status
549
+ 7. **Track trends** - Use memoryTrend to detect slow memory leaks
550
+ 8. **Test thoroughly** - Validate metrics accuracy in your specific environment
551
+
552
+ ## Troubleshooting
553
+
554
+ ### High Memory Usage
555
+
556
+ - Increase collection intervals
557
+ - Reduce number of active packages
558
+ - Use shorter recommendation strings
559
+ - Check for memory leaks using memoryTrend
560
+
561
+ ### Network Congestion
562
+
563
+ - Increase collection intervals
564
+ - Use SINGLE routing instead of BROADCAST for some packages
565
+ - Implement throttling based on network health
566
+ - Reduce message size by removing optional fields
567
+
568
+ ### Inaccurate Metrics
569
+
570
+ - Calibrate CPU usage calculation for your use case
571
+ - Validate timing measurements
572
+ - Check clock synchronization across mesh
573
+ - Verify RSSI readings match reality
574
+
575
+ ## Future Enhancements
576
+
577
+ Planned for v1.8.0:
578
+ - Compressed metric packages for large meshes
579
+ - Historical trend storage in gateway
580
+ - Automatic threshold tuning
581
+ - Machine learning-based failure prediction
582
+ - Integration with cloud monitoring services
583
+
584
+ ## Enhanced MQTT Bridge
585
+
586
+ ### Overview
587
+
588
+ The enhanced MQTT bridge (`examples/bridge/enhanced_mqtt_bridge.hpp`) extends the basic MQTT status bridge with command handlers and aggregation capabilities.
589
+
590
+ ### Features
591
+
592
+ 1. **Command Handlers** - Request metrics and health checks on-demand
593
+ 2. **Aggregated Statistics** - Mesh-wide metrics and health summaries
594
+ 3. **Automatic Caching** - Stores recent metrics for aggregation
595
+ 4. **Alert Detection** - Automatic critical health alerting
596
+ 5. **Response Topics** - Dedicated topics for command responses
597
+
598
+ ### MQTT Topics
599
+
600
+ #### Subscribe Topics (Commands)
601
+
602
+ | Topic | Payload | Description |
603
+ |-------|---------|-------------|
604
+ | `mesh/command/request_metrics` | `{"node_id": 0}` | Request metrics (0=all nodes) |
605
+ | `mesh/command/request_health` | `{"node_id": 12345}` | Request health check |
606
+ | `mesh/command/get_aggregated` | `{}` | Get current aggregated stats |
607
+
608
+ #### Publish Topics (Data)
609
+
610
+ | Topic | Description | Update Frequency |
611
+ |-------|-------------|------------------|
612
+ | `mesh/metrics/{node_id}` | Individual node metrics | When received from node |
613
+ | `mesh/health/{node_id}` | Individual node health | When received from node |
614
+ | `mesh/aggregated/metrics` | Mesh-wide metrics | Configurable (default 60s) |
615
+ | `mesh/aggregated/health` | Mesh health summary | Configurable (default 60s) |
616
+ | `mesh/alerts/critical` | Critical health alerts | When critical detected |
617
+ | `mesh/response/metrics` | Metrics command response | When node responds |
618
+ | `mesh/response/health` | Health command response | When node responds |
619
+
620
+ ### Aggregated Metrics Format
621
+
622
+ ```json
623
+ {
624
+ "node_count": 10,
625
+ "avg_cpu": 42,
626
+ "avg_heap": 125000,
627
+ "min_heap": 95000,
628
+ "max_heap": 150000,
629
+ "total_throughput": 81920,
630
+ "avg_quality": 87,
631
+ "min_quality": 65,
632
+ "max_quality": 98,
633
+ "avg_rssi": -58,
634
+ "timestamp": "2025-10-23T21:30:00Z"
635
+ }
636
+ ```
637
+
638
+ ### Aggregated Health Format
639
+
640
+ ```json
641
+ {
642
+ "node_count": 10,
643
+ "mesh_health": 2,
644
+ "healthy_nodes": 8,
645
+ "warning_nodes": 2,
646
+ "critical_nodes": 0,
647
+ "aggregated_problems": 5,
648
+ "avg_memory_health": 82,
649
+ "avg_network_health": 88,
650
+ "avg_performance_health": 90,
651
+ "timestamp": "2025-10-23T21:30:00Z"
652
+ }
653
+ ```
654
+
655
+ ### Example Usage
656
+
657
+ #### Request Metrics from All Nodes
658
+
659
+ ```bash
660
+ mosquitto_pub -h localhost -t mesh/command/request_metrics \
661
+ -m '{"node_id": 0}'
662
+ ```
663
+
664
+ #### Request Health from Specific Node
665
+
666
+ ```bash
667
+ mosquitto_pub -h localhost -t mesh/command/request_health \
668
+ -m '{"node_id": 12345}'
669
+ ```
670
+
671
+ #### Get Current Aggregated Statistics
672
+
673
+ ```bash
674
+ mosquitto_pub -h localhost -t mesh/command/get_aggregated -m '{}'
675
+ ```
676
+
677
+ #### Subscribe to Aggregated Metrics
678
+
679
+ ```bash
680
+ mosquitto_sub -h localhost -t mesh/aggregated/metrics
681
+ ```
682
+
683
+ #### Subscribe to Critical Alerts
684
+
685
+ ```bash
686
+ mosquitto_sub -h localhost -t mesh/alerts/critical
687
+ ```
688
+
689
+ ### Integration Example
690
+
691
+ ```cpp
692
+ #include "enhanced_mqtt_bridge.hpp"
693
+
694
+ // In setup()
695
+ EnhancedMqttBridge bridge(mesh, mqttClient);
696
+ bridge.setTopicPrefix("mesh/");
697
+ bridge.enableAggregation(true);
698
+ bridge.setAggregationInterval(60000); // 60 seconds
699
+ bridge.begin();
700
+
701
+ // In loop()
702
+ bridge.update();
703
+
704
+ // In MQTT callback
705
+ void mqttCallback(char* topic, byte* payload, unsigned int length) {
706
+ String topicStr = String(topic);
707
+ String payloadStr = String((char*)payload).substring(0, length);
708
+ bridge.handleMQTTMessage(topicStr, payloadStr);
709
+ }
710
+ ```
711
+
712
+ ### Configuration
713
+
714
+ ```cpp
715
+ // Set custom topic prefix
716
+ bridge.setTopicPrefix("alteriom/mesh/");
717
+
718
+ // Set device ID
719
+ bridge.setDeviceId("GATEWAY-001");
720
+
721
+ // Enable/disable aggregation
722
+ bridge.enableAggregation(true);
723
+
724
+ // Set aggregation interval
725
+ bridge.setAggregationInterval(30000); // 30 seconds
726
+ ```
727
+
728
+ ### Mesh Node Implementation
729
+
730
+ Nodes must respond to command requests:
731
+
732
+ ```cpp
733
+ void receivedCallback(uint32_t from, String& msg) {
734
+ DynamicJsonDocument doc(1024);
735
+ deserializeJson(doc, msg);
736
+
737
+ uint8_t msgType = doc["type"];
738
+
739
+ if (msgType == 201) { // CommandPackage
740
+ uint8_t command = doc["cmd"];
741
+
742
+ if (command == 210) { // Request metrics
743
+ sendMetrics();
744
+ } else if (command == 211) { // Request health
745
+ sendHealthCheck();
746
+ }
747
+ }
748
+ }
749
+ ```
750
+
751
+ ### Performance Considerations
752
+
753
+ **Memory Usage:**
754
+ - Cache size: ~100 bytes per node (max 20 nodes)
755
+ - Total overhead: ~2KB for bridge + caching
756
+
757
+ **Network Bandwidth:**
758
+ - Aggregated metrics: ~200 bytes every 60s
759
+ - Per-node metrics: ~200 bytes when received
760
+ - Critical alerts: ~150 bytes when detected
761
+
762
+ **Optimization:**
763
+ - Adjust cache size via `MAX_STORED_NODES` constant
764
+ - Increase aggregation interval for lower bandwidth
765
+ - Disable aggregation if not needed
766
+
767
+ ## Support
768
+
769
+ - **GitHub Issues**: https://github.com/Alteriom/painlessMesh/issues
770
+ - **Documentation**: https://alteriom.github.io/painlessMesh/
771
+ - **Examples**: `examples/alteriom/metrics_health_node.ino`, `examples/bridge/enhanced_mqtt_bridge_example.ino`
772
+
773
+ ## Changelog
774
+
775
+ ### v1.7.7 (2025-10-23)
776
+
777
+ **Added:**
778
+ - MetricsPackage (Type 204) for comprehensive performance monitoring
779
+ - HealthCheckPackage (Type 605) for proactive health monitoring (MESH_METRICS)
780
+ - Complete test suite for new packages
781
+ - Example implementation in `metrics_health_node.ino`
782
+ - Documentation for MQTT integration
783
+ - Dashboard integration examples
784
+
785
+ **Improved:**
786
+ - MQTT communication efficiency for metrics and health monitoring
787
+ - Problem detection and alerting capabilities
788
+ - Predictive maintenance support
789
+ - Memory leak detection
790
+
791
+ **Compatibility:**
792
+ - 100% backward compatible with v1.7.6
793
+ - All existing packages (200-203) unchanged
794
+ - Optional adoption of new features