@alteriom/painlessmesh 1.8.14 → 1.9.0

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 (208) hide show
  1. package/BRIDGE_TO_INTERNET.md +229 -0
  2. package/CHANGELOG.md +89 -1
  3. package/CONTRIBUTING.md +79 -0
  4. package/README.md +70 -143
  5. package/docs/README.md +1 -0
  6. package/docs/api/shared-gateway.md +1207 -0
  7. package/docs/troubleshooting/common-issues.md +28 -0
  8. package/docs/troubleshooting/faq.md +113 -12
  9. package/examples/basic/test/simulator/CMakeLists.txt +40 -0
  10. package/examples/basic/test/simulator/README.md +149 -0
  11. package/examples/basic/test/simulator/firmware/basic_firmware.hpp +117 -0
  12. package/examples/basic/test/simulator/scenarios/basic_mesh_test.yaml +81 -0
  13. package/examples/bridge/bridge.ino +17 -4
  14. package/examples/bridge_failover/README.md +81 -0
  15. package/examples/bridge_failover/bridge_failover.ino +51 -6
  16. package/examples/sharedGateway/README.md +235 -0
  17. package/examples/{meshCommandNode → sharedGateway}/platformio.ini +3 -2
  18. package/examples/sharedGateway/sharedGateway.ino +303 -0
  19. package/library.json +3 -22
  20. package/library.properties +1 -1
  21. package/package.json +3 -3
  22. package/src/arduino/wifi.hpp +380 -13
  23. package/src/painlessmesh/gateway.hpp +2120 -0
  24. package/src/painlessmesh/mesh.hpp +1034 -6
  25. package/src/painlessmesh/message_tracker.hpp +311 -0
  26. package/src/painlessmesh/protocol.hpp +6 -0
  27. package/DOCUMENTATION_INDEX.md +0 -146
  28. package/docs/API_DESIGN_GUIDELINES.md +0 -414
  29. package/docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md +0 -331
  30. package/docs/BOOLEAN_NAMING_CONVENTION.md +0 -235
  31. package/docs/BRIDGE_FAILOVER.md +0 -512
  32. package/docs/BRIDGE_HEALTH_MONITORING.md +0 -293
  33. package/docs/CHANNEL_SYNCHRONIZATION.md +0 -209
  34. package/docs/CREATE_MISSING_RELEASES.md +0 -321
  35. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +0 -176
  36. package/docs/FAQ_VERSION_NUMBERS.md +0 -152
  37. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +0 -1062
  38. package/docs/MESH_TOPOLOGY_GUIDE.md +0 -992
  39. package/docs/MESH_TOPOLOGY_PROGRESS.md +0 -422
  40. package/docs/MQTT_BRIDGE_COMMANDS.md +0 -894
  41. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +0 -324
  42. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +0 -576
  43. package/docs/MQTT_SCHEMA_COMPLIANCE.md +0 -340
  44. package/docs/MQTT_SCHEMA_PROPOSALS.md +0 -446
  45. package/docs/MQTT_SCHEMA_REVIEW.md +0 -690
  46. package/docs/OTA_COMMANDS_REFERENCE.md +0 -554
  47. package/docs/PHASE1_GUIDE.md +0 -349
  48. package/docs/PHASE2_GUIDE.md +0 -543
  49. package/docs/QUICK_REFERENCE_VERSIONING.md +0 -127
  50. package/docs/RELEASE_AGENT_SUMMARY.md +0 -386
  51. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +0 -222
  52. package/docs/VERSION_MANAGEMENT.md +0 -213
  53. package/docs/archive/DOCUSAURUS_DEPLOYMENT.md +0 -166
  54. package/docs/archive/FEATURE_PROPOSALS.md +0 -337
  55. package/docs/archive/LIBRARY_JSON_FIX.md +0 -98
  56. package/docs/archive/LIBRARY_STRUCTURE_FIX.md +0 -215
  57. package/docs/archive/PHASE1_IMPLEMENTATION.md +0 -325
  58. package/docs/archive/PHASE2_IMPLEMENTATION.md +0 -567
  59. package/docs/archive/RELEASE_SUMMARY.md +0 -173
  60. package/docs/archive/SCONS_BUILD_FIX.md +0 -313
  61. package/docs/archive/TRIGGER_RELEASE.md +0 -280
  62. package/docs/archive/VECTOR_INCLUDE_FIX.md +0 -129
  63. package/docs/archive/ota-and-status-enhancements.md +0 -911
  64. package/docs/archive/ota-status-architecture-diagrams.md +0 -658
  65. package/docs/archive/ota-status-quick-reference.md +0 -284
  66. package/docs/design/.gitkeep +0 -1
  67. package/docs/design/STATION_CREDENTIALS_DESIGN.md +0 -182
  68. package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +0 -71
  69. package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +0 -1011
  70. package/docs/development/DOCKER_TESTING.md +0 -196
  71. package/docs/development/PLATFORMIO_USAGE.md +0 -180
  72. package/docs/development/TESTING_SUMMARY.md +0 -126
  73. package/docs/development/contributing.md +0 -301
  74. package/docs/development/documentation.md +0 -583
  75. package/docs/features/DIAGNOSTICS_API.md +0 -534
  76. package/docs/implementation/BRIDGE_ARCHITECTURE_IMPLEMENTATION.md +0 -340
  77. package/docs/implementation/BRIDGE_HEALTH_MONITORING_IMPLEMENTATION.md +0 -213
  78. package/docs/implementation/BRIDGE_STATUS_FEATURE.md +0 -635
  79. package/docs/implementation/DIAGNOSTICS_API_IMPLEMENTATION.md +0 -232
  80. package/docs/implementation/IMPLEMENTATION_COMPLETE.md +0 -228
  81. package/docs/implementation/IMPLEMENTATION_NTP_TIME_SYNC.md +0 -325
  82. package/docs/implementation/IMPLEMENTATION_SUMMARY.md +0 -316
  83. package/docs/implementation/MESSAGE_QUEUE_IMPLEMENTATION.md +0 -405
  84. package/docs/implementation/MULTI_BRIDGE_IMPLEMENTATION.md +0 -520
  85. package/docs/implementation/NTP_TIME_SYNC_FEATURE.md +0 -392
  86. package/docs/improvements/FUTURE_PROPOSALS.md +0 -1016
  87. package/docs/improvements/IMPLEMENTATION_HISTORY.md +0 -1091
  88. package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +0 -709
  89. package/docs/improvements/README.md +0 -212
  90. package/docs/internal/CUSTOM_AGENT_ANALYSIS.md +0 -391
  91. package/docs/internal/ISSUE_65_VERIFICATION.md +0 -947
  92. package/docs/internal/ISSUE_66_CLOSURE.md +0 -249
  93. package/docs/internal/ISSUE_66_STATUS.md +0 -316
  94. package/docs/internal/PR_SUMMARY.md +0 -315
  95. package/docs/internal/REVIEW_SUMMARY.md +0 -332
  96. package/docs/multi-bridge-setup.md +0 -1025
  97. package/docs/platformio-publishing.md +0 -255
  98. package/docs/platformio-setup-summary.md +0 -121
  99. package/docs/releases/ANNOUNCEMENT_v1.8.6.md +0 -63
  100. package/docs/releases/ANNOUNCEMENT_v1.8.7.md +0 -113
  101. package/docs/releases/BRIDGE_STATUS_SELF_REGISTRATION_FIX.md +0 -221
  102. package/docs/releases/FEATURE_HISTORY.md +0 -543
  103. package/docs/releases/GITHUB_RELEASE_v1.8.6.md +0 -71
  104. package/docs/releases/GITHUB_RELEASE_v1.8.7.md +0 -90
  105. package/docs/releases/PATCH_v1.7.2.md +0 -262
  106. package/docs/releases/PATCH_v1.7.3.md +0 -262
  107. package/docs/releases/PATCH_v1.7.4.md +0 -219
  108. package/docs/releases/PHASE1_SUMMARY.md +0 -246
  109. package/docs/releases/PHASE2_SUMMARY.md +0 -499
  110. package/docs/releases/PUBLISH_v1.8.0_INSTRUCTIONS.md +0 -163
  111. package/docs/releases/QUICK_START_RELEASES.md +0 -113
  112. package/docs/releases/RELEASE_CHECKLIST_1.8.10.md +0 -331
  113. package/docs/releases/RELEASE_CHECKLIST_1.8.9.md +0 -207
  114. package/docs/releases/RELEASE_CHECKLIST_v1.7.4.md +0 -253
  115. package/docs/releases/RELEASE_CHECKLIST_v1.7.5.md +0 -315
  116. package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +0 -389
  117. package/docs/releases/RELEASE_CHECKLIST_v1.8.0.md +0 -331
  118. package/docs/releases/RELEASE_CHECKLIST_v1.8.2.md +0 -309
  119. package/docs/releases/RELEASE_NOTES_1.7.0.md +0 -539
  120. package/docs/releases/RELEASE_NOTES_1.8.10.md +0 -239
  121. package/docs/releases/RELEASE_NOTES_1.8.9.md +0 -213
  122. package/docs/releases/RELEASE_NOTES_v1.8.0.md +0 -685
  123. package/docs/releases/RELEASE_NOTES_v1.8.1.md +0 -221
  124. package/docs/releases/RELEASE_NOTES_v1.8.2.md +0 -421
  125. package/docs/releases/RELEASE_NOTES_v1.8.3.md +0 -292
  126. package/docs/releases/RELEASE_NOTES_v1.8.4.md +0 -277
  127. package/docs/releases/RELEASE_NOTES_v1.8.6.md +0 -205
  128. package/docs/releases/RELEASE_NOTES_v1.8.7.md +0 -184
  129. package/docs/releases/RELEASE_PLAN_v1.7.6.md +0 -816
  130. package/docs/releases/RELEASE_SUMMARY_1.8.10.md +0 -193
  131. package/docs/releases/RELEASE_SUMMARY_v1.7.4.md +0 -276
  132. package/docs/releases/RELEASE_SUMMARY_v1.7.5.md +0 -322
  133. package/docs/releases/RELEASE_SUMMARY_v1.7.6.md +0 -436
  134. package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +0 -391
  135. package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +0 -523
  136. package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +0 -542
  137. package/docs/troubleshooting/ARDUINO_IDE_VERSION_FIX_SUMMARY.md +0 -229
  138. package/docs/troubleshooting/ARDUINO_LIBRARY_NAME_FIX.md +0 -197
  139. package/docs/troubleshooting/CRASH_QUICK_REF.md +0 -93
  140. package/docs/troubleshooting/ESP32_C6_COMPATIBILITY.md +0 -157
  141. package/docs/troubleshooting/FREERTOS_ASSERTION_FAILURE.md +0 -288
  142. package/docs/troubleshooting/FREERTOS_FIX_IMPLEMENTATION.md +0 -267
  143. package/docs/troubleshooting/NPM_PUBLISHING_ISSUE_SUMMARY.md +0 -110
  144. package/docs/troubleshooting/PAINLESSMESH_V1.7.4_COMPILATION_ISSUES.md +0 -547
  145. package/docs/troubleshooting/QUICK_FIX_FREERTOS.md +0 -164
  146. package/docs/troubleshooting/SENSOR_NODE_CONNECTION_CRASH.md +0 -264
  147. package/docs/troubleshooting/station-reconnection-issues.md +0 -172
  148. package/docs/v1.7.7_MQTT_IMPROVEMENTS.md +0 -794
  149. package/docs/wiki/API-Reference.md +0 -246
  150. package/docs/wiki/Complete-Documentation.md +0 -123
  151. package/examples/alteriomImproved/alteriom_sensor_package.hpp +0 -224
  152. package/examples/alteriomImproved/improved_sensor_node.ino +0 -248
  153. package/examples/alteriomImproved/platformio.ini +0 -32
  154. package/examples/alteriomMetricsHealth/alteriom_sensor_package.hpp +0 -796
  155. package/examples/alteriomMetricsHealth/metrics_health_node.ino +0 -429
  156. package/examples/alteriomMetricsHealth/platformio.ini +0 -26
  157. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +0 -224
  158. package/examples/alteriomPhase1/phase1_features.ino +0 -242
  159. package/examples/alteriomPhase1/platformio.ini +0 -26
  160. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +0 -224
  161. package/examples/alteriomPhase2/phase2_features.ino +0 -186
  162. package/examples/alteriomPhase2/platformio.ini +0 -26
  163. package/examples/alteriomSensorNode/alteriom_sensor_node.ino +0 -186
  164. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +0 -1227
  165. package/examples/alteriomSensorNode/platformio.ini +0 -26
  166. package/examples/bridge/alteriom_sensor_package.hpp +0 -1170
  167. package/examples/bridge/bridge_health_monitoring_example.ino +0 -188
  168. package/examples/bridge/enhanced_mqtt_bridge.hpp +0 -610
  169. package/examples/bridge/enhanced_mqtt_bridge_example.ino +0 -226
  170. package/examples/bridge/mesh_event_publisher.hpp +0 -253
  171. package/examples/bridge/mesh_topology_reporter.hpp +0 -303
  172. package/examples/bridge/mqtt_command_bridge.hpp +0 -459
  173. package/examples/bridge/mqtt_status_bridge.hpp +0 -519
  174. package/examples/bridgeAwareSensorNode/alteriom_sensor_package.hpp +0 -1227
  175. package/examples/bridgeAwareSensorNode/bridgeAwareSensorNode.ino +0 -342
  176. package/examples/bridgeAwareSensorNode/platformio.ini +0 -26
  177. package/examples/diagnosticsExample/diagnosticsExample.ino +0 -171
  178. package/examples/diagnosticsExample/platformio.ini +0 -26
  179. package/examples/echoNode/echoNode.ino +0 -33
  180. package/examples/echoNode/platformio.ini +0 -26
  181. package/examples/meshCommandNode/alteriom_sensor_package.hpp +0 -235
  182. package/examples/meshCommandNode/meshCommandNode.ino +0 -265
  183. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +0 -235
  184. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +0 -253
  185. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +0 -303
  186. package/examples/mqttCommandBridge/mqttCommandBridge.ino +0 -254
  187. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +0 -462
  188. package/examples/mqttCommandBridge/platformio.ini +0 -27
  189. package/examples/mqttStatusBridge/mqttStatusBridge.ino +0 -218
  190. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +0 -522
  191. package/examples/mqttStatusBridge/platformio.ini +0 -27
  192. package/examples/mqttTopologyTest/README.md +0 -467
  193. package/examples/mqttTopologyTest/mqttTopologyTest.ino +0 -754
  194. package/examples/mqttTopologyTest/platformio.ini +0 -27
  195. package/examples/multi_bridge/README.md +0 -346
  196. package/examples/multi_bridge/primary_bridge.ino +0 -96
  197. package/examples/multi_bridge/regular_node.ino +0 -141
  198. package/examples/multi_bridge/secondary_bridge.ino +0 -111
  199. package/examples/ntpTimeSyncBridge/alteriom_sensor_package.hpp +0 -1383
  200. package/examples/ntpTimeSyncBridge/ntpTimeSyncBridge.ino +0 -86
  201. package/examples/ntpTimeSyncNode/alteriom_sensor_package.hpp +0 -1383
  202. package/examples/ntpTimeSyncNode/ntpTimeSyncNode.ino +0 -109
  203. package/examples/queued_alarms/README.md +0 -390
  204. package/examples/queued_alarms/queued_alarms.ino +0 -265
  205. package/examples/routing_demo/README.md +0 -172
  206. package/examples/routing_demo/routing_demo.ino +0 -102
  207. package/examples/rtcIntegration/README.md +0 -294
  208. package/examples/rtcIntegration/rtcIntegration.ino +0 -210
@@ -1,610 +0,0 @@
1
- #ifndef _ENHANCED_MQTT_BRIDGE_HPP_
2
- #define _ENHANCED_MQTT_BRIDGE_HPP_
3
-
4
- /**
5
- * Enhanced MQTT Bridge for painlessMesh v1.7.7+
6
- *
7
- * Extends the basic MQTT bridge with:
8
- * - Command handlers for requesting specific metrics
9
- * - Aggregated network statistics
10
- * - Support for MetricsPackage (Type 204) and HealthCheckPackage (Type 605)
11
- * - Real-time metric requests and responses
12
- * - Network-wide health aggregation
13
- *
14
- * MQTT Topics:
15
- * Subscribe:
16
- * - mesh/command/request_metrics - Request metrics from specific node or all nodes
17
- * - mesh/command/request_health - Request health check from specific node or all nodes
18
- * - mesh/command/get_aggregated - Get aggregated statistics
19
- *
20
- * Publish:
21
- * - mesh/metrics/{node_id} - Individual node metrics
22
- * - mesh/health/{node_id} - Individual node health
23
- * - mesh/aggregated/metrics - Aggregated mesh-wide metrics
24
- * - mesh/aggregated/health - Aggregated mesh-wide health summary
25
- * - mesh/response/metrics - Metrics response to command
26
- * - mesh/response/health - Health response to command
27
- */
28
-
29
- #include <Arduino.h>
30
- #include <painlessMesh.h>
31
- #include <PubSubClient.h>
32
- #include "alteriom_sensor_package.hpp"
33
-
34
- using namespace alteriom;
35
-
36
- // Command types for metric requests
37
- #define CMD_REQUEST_METRICS 210
38
- #define CMD_REQUEST_HEALTH 211
39
- #define CMD_METRICS_RESPONSE 212
40
- #define CMD_HEALTH_RESPONSE 213
41
-
42
- class EnhancedMqttBridge {
43
- private:
44
- painlessMesh& mesh;
45
- PubSubClient& mqttClient;
46
-
47
- // Configuration
48
- String topicPrefix = "mesh/";
49
- String deviceId = "";
50
- String firmwareVersion = "1.7.7";
51
-
52
- // Aggregation settings
53
- bool enableAggregation = true;
54
- uint32_t aggregationInterval = 60000; // 60 seconds
55
- unsigned long lastAggregationTime = 0;
56
-
57
- // Metric storage for aggregation
58
- struct NodeMetrics {
59
- uint32_t nodeId;
60
- uint32_t timestamp;
61
- uint8_t cpuUsage;
62
- uint32_t freeHeap;
63
- uint16_t currentThroughput;
64
- uint8_t connectionQuality;
65
- int8_t wifiRSSI;
66
- };
67
-
68
- struct NodeHealth {
69
- uint32_t nodeId;
70
- uint32_t timestamp;
71
- uint8_t healthStatus;
72
- uint16_t problemFlags;
73
- uint8_t memoryHealth;
74
- uint8_t networkHealth;
75
- uint8_t performanceHealth;
76
- };
77
-
78
- // Storage (limited to prevent memory issues)
79
- #define MAX_STORED_NODES 20
80
- NodeMetrics metricsCache[MAX_STORED_NODES];
81
- NodeHealth healthCache[MAX_STORED_NODES];
82
- uint8_t metricsCacheSize = 0;
83
- uint8_t healthCacheSize = 0;
84
-
85
- // Callback for processing received mesh messages
86
- std::function<void(uint32_t, String&)> originalReceiveCallback = nullptr;
87
-
88
- public:
89
- /**
90
- * Constructor
91
- */
92
- EnhancedMqttBridge(painlessMesh& mesh, PubSubClient& mqttClient)
93
- : mesh(mesh), mqttClient(mqttClient) {
94
- }
95
-
96
- /**
97
- * Initialize the enhanced bridge
98
- */
99
- void begin() {
100
- // Set device ID if not already set
101
- if (deviceId.length() == 0) {
102
- deviceId = "ALT-" + String(mesh.getNodeId(), HEX);
103
- deviceId.toUpperCase();
104
- }
105
-
106
- // Subscribe to command topics
107
- subscribeMQTTCommands();
108
-
109
- // Set up mesh message handler
110
- setupMeshCallbacks();
111
-
112
- Serial.println("Enhanced MQTT Bridge v1.7.7 started");
113
- Serial.printf("Device ID: %s\n", deviceId.c_str());
114
- Serial.println("Command topics subscribed:");
115
- Serial.printf(" - %scommand/request_metrics\n", topicPrefix.c_str());
116
- Serial.printf(" - %scommand/request_health\n", topicPrefix.c_str());
117
- Serial.printf(" - %scommand/get_aggregated\n", topicPrefix.c_str());
118
- }
119
-
120
- /**
121
- * Update function - call in loop()
122
- */
123
- void update() {
124
- // Check if it's time to publish aggregated statistics
125
- if (enableAggregation && (millis() - lastAggregationTime > aggregationInterval)) {
126
- publishAggregatedMetrics();
127
- publishAggregatedHealth();
128
- lastAggregationTime = millis();
129
- }
130
- }
131
-
132
- /**
133
- * Set topic prefix
134
- */
135
- void setTopicPrefix(const String& prefix) {
136
- topicPrefix = prefix;
137
- }
138
-
139
- /**
140
- * Set device ID
141
- */
142
- void setDeviceId(const String& id) {
143
- deviceId = id;
144
- }
145
-
146
- /**
147
- * Enable/disable aggregation
148
- */
149
- void enableAggregation(bool enable) {
150
- enableAggregation = enable;
151
- }
152
-
153
- /**
154
- * Set aggregation interval
155
- */
156
- void setAggregationInterval(uint32_t interval) {
157
- aggregationInterval = interval;
158
- }
159
-
160
- /**
161
- * Handle incoming MQTT messages
162
- * Call this from your MQTT callback
163
- */
164
- void handleMQTTMessage(String& topic, String& payload) {
165
- Serial.printf("MQTT message received on topic: %s\n", topic.c_str());
166
-
167
- if (topic == topicPrefix + "command/request_metrics") {
168
- handleRequestMetrics(payload);
169
- } else if (topic == topicPrefix + "command/request_health") {
170
- handleRequestHealth(payload);
171
- } else if (topic == topicPrefix + "command/get_aggregated") {
172
- handleGetAggregated(payload);
173
- }
174
- }
175
-
176
- private:
177
- /**
178
- * Subscribe to MQTT command topics
179
- */
180
- void subscribeMQTTCommands() {
181
- String topic = topicPrefix + "command/request_metrics";
182
- mqttClient.subscribe(topic.c_str());
183
-
184
- topic = topicPrefix + "command/request_health";
185
- mqttClient.subscribe(topic.c_str());
186
-
187
- topic = topicPrefix + "command/get_aggregated";
188
- mqttClient.subscribe(topic.c_str());
189
- }
190
-
191
- /**
192
- * Set up mesh callbacks to intercept packages
193
- */
194
- void setupMeshCallbacks() {
195
- mesh.onReceive([this](uint32_t from, String& msg) {
196
- this->handleMeshMessage(from, msg);
197
- });
198
- }
199
-
200
- /**
201
- * Handle mesh messages and extract metrics/health packages
202
- */
203
- void handleMeshMessage(uint32_t from, String& msg) {
204
- // Parse message to determine type
205
- DynamicJsonDocument doc(2048);
206
- DeserializationError error = deserializeJson(doc, msg);
207
-
208
- if (error) {
209
- Serial.printf("JSON parse error from node %u: %s\n", from, error.c_str());
210
- return;
211
- }
212
-
213
- JsonObject obj = doc.as<JsonObject>();
214
- uint8_t msgType = obj["type"];
215
-
216
- // Handle different package types
217
- switch(msgType) {
218
- case 204: // MetricsPackage (SENSOR_METRICS per schema v0.7.2+)
219
- handleMetricsPackage(from, obj);
220
- break;
221
- case 605: // HealthCheckPackage (MESH_METRICS per schema v0.7.2+)
222
- handleHealthPackage(from, obj);
223
- break;
224
- case CMD_METRICS_RESPONSE:
225
- handleMetricsResponse(from, obj);
226
- break;
227
- case CMD_HEALTH_RESPONSE:
228
- handleHealthResponse(from, obj);
229
- break;
230
- }
231
-
232
- // Call original callback if set
233
- if (originalReceiveCallback) {
234
- originalReceiveCallback(from, msg);
235
- }
236
- }
237
-
238
- /**
239
- * Handle MetricsPackage received from mesh
240
- */
241
- void handleMetricsPackage(uint32_t from, JsonObject& obj) {
242
- Serial.printf("Received MetricsPackage from node %u\n", from);
243
-
244
- // Store in cache for aggregation
245
- storeMetrics(from, obj);
246
-
247
- // Publish to MQTT
248
- publishMetricsToMQTT(from, obj);
249
- }
250
-
251
- /**
252
- * Handle HealthCheckPackage received from mesh
253
- */
254
- void handleHealthPackage(uint32_t from, JsonObject& obj) {
255
- Serial.printf("Received HealthCheckPackage from node %u\n", from);
256
-
257
- // Store in cache for aggregation
258
- storeHealth(from, obj);
259
-
260
- // Publish to MQTT
261
- publishHealthToMQTT(from, obj);
262
-
263
- // Check for critical health and alert
264
- uint8_t healthStatus = obj["health"];
265
- if (healthStatus == 0) {
266
- publishCriticalAlert(from, obj);
267
- }
268
- }
269
-
270
- /**
271
- * Store metrics in cache for aggregation
272
- */
273
- void storeMetrics(uint32_t nodeId, JsonObject& obj) {
274
- // Find existing entry or add new
275
- int index = findMetricsCacheIndex(nodeId);
276
- if (index == -1) {
277
- if (metricsCacheSize < MAX_STORED_NODES) {
278
- index = metricsCacheSize++;
279
- } else {
280
- // Cache full, replace oldest
281
- index = 0;
282
- }
283
- }
284
-
285
- metricsCache[index].nodeId = nodeId;
286
- metricsCache[index].timestamp = obj["ts"];
287
- metricsCache[index].cpuUsage = obj["cpu"];
288
- metricsCache[index].freeHeap = obj["heap"];
289
- metricsCache[index].currentThroughput = obj["throughput"];
290
- metricsCache[index].connectionQuality = obj["connQual"];
291
- metricsCache[index].wifiRSSI = obj["rssi"];
292
- }
293
-
294
- /**
295
- * Store health in cache for aggregation
296
- */
297
- void storeHealth(uint32_t nodeId, JsonObject& obj) {
298
- // Find existing entry or add new
299
- int index = findHealthCacheIndex(nodeId);
300
- if (index == -1) {
301
- if (healthCacheSize < MAX_STORED_NODES) {
302
- index = healthCacheSize++;
303
- } else {
304
- // Cache full, replace oldest
305
- index = 0;
306
- }
307
- }
308
-
309
- healthCache[index].nodeId = nodeId;
310
- healthCache[index].timestamp = obj["ts"];
311
- healthCache[index].healthStatus = obj["health"];
312
- healthCache[index].problemFlags = obj["problems"];
313
- healthCache[index].memoryHealth = obj["memHealth"];
314
- healthCache[index].networkHealth = obj["netHealth"];
315
- healthCache[index].performanceHealth = obj["perfHealth"];
316
- }
317
-
318
- /**
319
- * Find metrics cache index for node
320
- */
321
- int findMetricsCacheIndex(uint32_t nodeId) {
322
- for (int i = 0; i < metricsCacheSize; i++) {
323
- if (metricsCache[i].nodeId == nodeId) {
324
- return i;
325
- }
326
- }
327
- return -1;
328
- }
329
-
330
- /**
331
- * Find health cache index for node
332
- */
333
- int findHealthCacheIndex(uint32_t nodeId) {
334
- for (int i = 0; i < healthCacheSize; i++) {
335
- if (healthCache[i].nodeId == nodeId) {
336
- return i;
337
- }
338
- }
339
- return -1;
340
- }
341
-
342
- /**
343
- * Publish metrics to MQTT
344
- */
345
- void publishMetricsToMQTT(uint32_t from, JsonObject& obj) {
346
- String topic = topicPrefix + "metrics/" + String(from);
347
-
348
- // Build payload
349
- String payload;
350
- serializeJson(obj, payload);
351
-
352
- mqttClient.publish(topic.c_str(), payload.c_str());
353
- }
354
-
355
- /**
356
- * Publish health to MQTT
357
- */
358
- void publishHealthToMQTT(uint32_t from, JsonObject& obj) {
359
- String topic = topicPrefix + "health/" + String(from);
360
-
361
- // Build payload
362
- String payload;
363
- serializeJson(obj, payload);
364
-
365
- mqttClient.publish(topic.c_str(), payload.c_str());
366
- }
367
-
368
- /**
369
- * Publish critical health alert
370
- */
371
- void publishCriticalAlert(uint32_t from, JsonObject& obj) {
372
- String topic = topicPrefix + "alerts/critical";
373
-
374
- String payload = "{";
375
- payload += "\"alert_type\":\"critical_health\",";
376
- payload += "\"node_id\":" + String(from) + ",";
377
- payload += "\"health_status\":" + String((uint8_t)obj["health"]) + ",";
378
- payload += "\"problem_flags\":" + String((uint16_t)obj["problems"]) + ",";
379
- payload += "\"recommendations\":\"" + obj["recommend"].as<String>() + "\",";
380
- payload += "\"timestamp\":\"" + buildISO8601Timestamp() + "\"";
381
- payload += "}";
382
-
383
- mqttClient.publish(topic.c_str(), payload.c_str());
384
- Serial.printf("CRITICAL ALERT: Node %u health is critical!\n", from);
385
- }
386
-
387
- /**
388
- * Handle request metrics command from MQTT
389
- */
390
- void handleRequestMetrics(String& payload) {
391
- Serial.println("Handling request_metrics command");
392
-
393
- // Parse payload to get target node (0 = all nodes)
394
- DynamicJsonDocument doc(256);
395
- deserializeJson(doc, payload);
396
- uint32_t targetNode = doc["node_id"] | 0;
397
-
398
- // Create command package
399
- CommandPackage cmd;
400
- cmd.from = mesh.getNodeId();
401
- cmd.dest = targetNode;
402
- cmd.command = CMD_REQUEST_METRICS;
403
- cmd.commandId = millis();
404
-
405
- // Send to mesh
406
- String msg = cmd.toJsonString();
407
- if (targetNode == 0) {
408
- mesh.sendBroadcast(msg);
409
- Serial.println("Metrics requested from all nodes");
410
- } else {
411
- mesh.sendSingle(targetNode, msg);
412
- Serial.printf("Metrics requested from node %u\n", targetNode);
413
- }
414
- }
415
-
416
- /**
417
- * Handle request health command from MQTT
418
- */
419
- void handleRequestHealth(String& payload) {
420
- Serial.println("Handling request_health command");
421
-
422
- // Parse payload to get target node (0 = all nodes)
423
- DynamicJsonDocument doc(256);
424
- deserializeJson(doc, payload);
425
- uint32_t targetNode = doc["node_id"] | 0;
426
-
427
- // Create command package
428
- CommandPackage cmd;
429
- cmd.from = mesh.getNodeId();
430
- cmd.dest = targetNode;
431
- cmd.command = CMD_REQUEST_HEALTH;
432
- cmd.commandId = millis();
433
-
434
- // Send to mesh
435
- String msg = cmd.toJsonString();
436
- if (targetNode == 0) {
437
- mesh.sendBroadcast(msg);
438
- Serial.println("Health check requested from all nodes");
439
- } else {
440
- mesh.sendSingle(targetNode, msg);
441
- Serial.printf("Health check requested from node %u\n", targetNode);
442
- }
443
- }
444
-
445
- /**
446
- * Handle get aggregated command from MQTT
447
- */
448
- void handleGetAggregated(String& payload) {
449
- Serial.println("Handling get_aggregated command");
450
-
451
- // Immediately publish current aggregated stats
452
- publishAggregatedMetrics();
453
- publishAggregatedHealth();
454
- }
455
-
456
- /**
457
- * Handle metrics response from node
458
- */
459
- void handleMetricsResponse(uint32_t from, JsonObject& obj) {
460
- Serial.printf("Received metrics response from node %u\n", from);
461
-
462
- // Publish to response topic
463
- String topic = topicPrefix + "response/metrics";
464
- String payload;
465
- serializeJson(obj, payload);
466
- mqttClient.publish(topic.c_str(), payload.c_str());
467
- }
468
-
469
- /**
470
- * Handle health response from node
471
- */
472
- void handleHealthResponse(uint32_t from, JsonObject& obj) {
473
- Serial.printf("Received health response from node %u\n", from);
474
-
475
- // Publish to response topic
476
- String topic = topicPrefix + "response/health";
477
- String payload;
478
- serializeJson(obj, payload);
479
- mqttClient.publish(topic.c_str(), payload.c_str());
480
- }
481
-
482
- /**
483
- * Publish aggregated metrics
484
- */
485
- void publishAggregatedMetrics() {
486
- if (metricsCacheSize == 0) {
487
- Serial.println("No metrics to aggregate");
488
- return;
489
- }
490
-
491
- // Calculate aggregated statistics
492
- uint32_t totalCPU = 0;
493
- uint32_t totalHeap = 0;
494
- uint32_t totalThroughput = 0;
495
- uint32_t totalQuality = 0;
496
- int32_t totalRSSI = 0;
497
- uint32_t minHeap = 0xFFFFFFFF;
498
- uint32_t maxHeap = 0;
499
- uint8_t minQuality = 100;
500
- uint8_t maxQuality = 0;
501
-
502
- for (int i = 0; i < metricsCacheSize; i++) {
503
- totalCPU += metricsCache[i].cpuUsage;
504
- totalHeap += metricsCache[i].freeHeap;
505
- totalThroughput += metricsCache[i].currentThroughput;
506
- totalQuality += metricsCache[i].connectionQuality;
507
- totalRSSI += metricsCache[i].wifiRSSI;
508
-
509
- if (metricsCache[i].freeHeap < minHeap) minHeap = metricsCache[i].freeHeap;
510
- if (metricsCache[i].freeHeap > maxHeap) maxHeap = metricsCache[i].freeHeap;
511
- if (metricsCache[i].connectionQuality < minQuality) minQuality = metricsCache[i].connectionQuality;
512
- if (metricsCache[i].connectionQuality > maxQuality) maxQuality = metricsCache[i].connectionQuality;
513
- }
514
-
515
- // Build aggregated payload
516
- String topic = topicPrefix + "aggregated/metrics";
517
- String payload = "{";
518
- payload += "\"node_count\":" + String(metricsCacheSize) + ",";
519
- payload += "\"avg_cpu\":" + String(totalCPU / metricsCacheSize) + ",";
520
- payload += "\"avg_heap\":" + String(totalHeap / metricsCacheSize) + ",";
521
- payload += "\"min_heap\":" + String(minHeap) + ",";
522
- payload += "\"max_heap\":" + String(maxHeap) + ",";
523
- payload += "\"total_throughput\":" + String(totalThroughput) + ",";
524
- payload += "\"avg_quality\":" + String(totalQuality / metricsCacheSize) + ",";
525
- payload += "\"min_quality\":" + String(minQuality) + ",";
526
- payload += "\"max_quality\":" + String(maxQuality) + ",";
527
- payload += "\"avg_rssi\":" + String(totalRSSI / metricsCacheSize) + ",";
528
- payload += "\"timestamp\":\"" + buildISO8601Timestamp() + "\"";
529
- payload += "}";
530
-
531
- mqttClient.publish(topic.c_str(), payload.c_str());
532
- Serial.printf("Published aggregated metrics for %d nodes\n", metricsCacheSize);
533
- }
534
-
535
- /**
536
- * Publish aggregated health
537
- */
538
- void publishAggregatedHealth() {
539
- if (healthCacheSize == 0) {
540
- Serial.println("No health data to aggregate");
541
- return;
542
- }
543
-
544
- // Count nodes by health status
545
- uint8_t healthyCount = 0;
546
- uint8_t warningCount = 0;
547
- uint8_t criticalCount = 0;
548
-
549
- // Aggregate problem flags
550
- uint16_t aggregatedProblems = 0;
551
-
552
- // Average health scores
553
- uint32_t totalMemHealth = 0;
554
- uint32_t totalNetHealth = 0;
555
- uint32_t totalPerfHealth = 0;
556
-
557
- for (int i = 0; i < healthCacheSize; i++) {
558
- // Count by status
559
- if (healthCache[i].healthStatus == 2) healthyCount++;
560
- else if (healthCache[i].healthStatus == 1) warningCount++;
561
- else criticalCount++;
562
-
563
- // Aggregate problems
564
- aggregatedProblems |= healthCache[i].problemFlags;
565
-
566
- // Sum health scores
567
- totalMemHealth += healthCache[i].memoryHealth;
568
- totalNetHealth += healthCache[i].networkHealth;
569
- totalPerfHealth += healthCache[i].performanceHealth;
570
- }
571
-
572
- // Determine overall mesh health
573
- uint8_t meshHealth = 2; // Healthy
574
- if (criticalCount > 0) meshHealth = 0; // Critical
575
- else if (warningCount > 0) meshHealth = 1; // Warning
576
-
577
- // Build aggregated payload
578
- String topic = topicPrefix + "aggregated/health";
579
- String payload = "{";
580
- payload += "\"node_count\":" + String(healthCacheSize) + ",";
581
- payload += "\"mesh_health\":" + String(meshHealth) + ",";
582
- payload += "\"healthy_nodes\":" + String(healthyCount) + ",";
583
- payload += "\"warning_nodes\":" + String(warningCount) + ",";
584
- payload += "\"critical_nodes\":" + String(criticalCount) + ",";
585
- payload += "\"aggregated_problems\":" + String(aggregatedProblems) + ",";
586
- payload += "\"avg_memory_health\":" + String(totalMemHealth / healthCacheSize) + ",";
587
- payload += "\"avg_network_health\":" + String(totalNetHealth / healthCacheSize) + ",";
588
- payload += "\"avg_performance_health\":" + String(totalPerfHealth / healthCacheSize) + ",";
589
- payload += "\"timestamp\":\"" + buildISO8601Timestamp() + "\"";
590
- payload += "}";
591
-
592
- mqttClient.publish(topic.c_str(), payload.c_str());
593
- Serial.printf("Published aggregated health: %d healthy, %d warning, %d critical\n",
594
- healthyCount, warningCount, criticalCount);
595
- }
596
-
597
- /**
598
- * Build ISO 8601 timestamp
599
- */
600
- String buildISO8601Timestamp() {
601
- // Simplified - in production use NTP time
602
- uint32_t uptime = millis() / 1000;
603
- char buffer[32];
604
- snprintf(buffer, sizeof(buffer), "1970-01-01T00:%02d:%02dZ",
605
- (uptime / 60) % 60, uptime % 60);
606
- return String(buffer);
607
- }
608
- };
609
-
610
- #endif // _ENHANCED_MQTT_BRIDGE_HPP_