@alteriom/painlessmesh 1.8.15 → 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 +61 -1
  3. package/CONTRIBUTING.md +79 -0
  4. package/README.md +69 -144
  5. package/docs/README.md +1 -0
  6. package/docs/api/shared-gateway.md +1207 -0
  7. package/examples/bridge_failover/README.md +81 -0
  8. package/examples/bridge_failover/bridge_failover.ino +35 -4
  9. package/examples/sharedGateway/README.md +235 -0
  10. package/examples/{meshCommandNode → sharedGateway}/platformio.ini +3 -2
  11. package/examples/sharedGateway/sharedGateway.ino +303 -0
  12. package/library.json +3 -22
  13. package/library.properties +1 -1
  14. package/package.json +3 -6
  15. package/src/arduino/wifi.hpp +342 -4
  16. package/src/painlessmesh/gateway.hpp +2120 -0
  17. package/src/painlessmesh/mesh.hpp +1034 -6
  18. package/src/painlessmesh/message_tracker.hpp +311 -0
  19. package/src/painlessmesh/protocol.hpp +6 -0
  20. package/DOCUMENTATION_INDEX.md +0 -146
  21. package/RELEASE_NOTES_1.8.15.md +0 -160
  22. package/RELEASE_READINESS_PLAN.md +0 -323
  23. package/TESTING_WITH_SIMULATOR.md +0 -259
  24. package/docs/API_DESIGN_GUIDELINES.md +0 -414
  25. package/docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md +0 -331
  26. package/docs/BOOLEAN_NAMING_CONVENTION.md +0 -235
  27. package/docs/BRIDGE_FAILOVER.md +0 -512
  28. package/docs/BRIDGE_HEALTH_MONITORING.md +0 -293
  29. package/docs/BRIDGE_INITIALIZATION_FALLBACK.md +0 -357
  30. package/docs/CHANNEL_SYNCHRONIZATION.md +0 -209
  31. package/docs/CREATE_MISSING_RELEASES.md +0 -321
  32. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +0 -176
  33. package/docs/FAQ_VERSION_NUMBERS.md +0 -152
  34. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +0 -1062
  35. package/docs/MESH_TOPOLOGY_GUIDE.md +0 -992
  36. package/docs/MESH_TOPOLOGY_PROGRESS.md +0 -422
  37. package/docs/MQTT_BRIDGE_COMMANDS.md +0 -894
  38. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +0 -324
  39. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +0 -576
  40. package/docs/MQTT_SCHEMA_COMPLIANCE.md +0 -340
  41. package/docs/MQTT_SCHEMA_PROPOSALS.md +0 -446
  42. package/docs/MQTT_SCHEMA_REVIEW.md +0 -690
  43. package/docs/OTA_COMMANDS_REFERENCE.md +0 -554
  44. package/docs/PHASE1_GUIDE.md +0 -349
  45. package/docs/PHASE2_GUIDE.md +0 -543
  46. package/docs/QUICK_REFERENCE_VERSIONING.md +0 -127
  47. package/docs/RELEASE_AGENT_SUMMARY.md +0 -386
  48. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +0 -222
  49. package/docs/SIMULATOR_TESTING.md +0 -408
  50. package/docs/VERSION_MANAGEMENT.md +0 -213
  51. package/docs/archive/DOCUSAURUS_DEPLOYMENT.md +0 -166
  52. package/docs/archive/FEATURE_PROPOSALS.md +0 -337
  53. package/docs/archive/LIBRARY_JSON_FIX.md +0 -98
  54. package/docs/archive/LIBRARY_STRUCTURE_FIX.md +0 -215
  55. package/docs/archive/PHASE1_IMPLEMENTATION.md +0 -325
  56. package/docs/archive/PHASE2_IMPLEMENTATION.md +0 -567
  57. package/docs/archive/RELEASE_SUMMARY.md +0 -173
  58. package/docs/archive/SCONS_BUILD_FIX.md +0 -313
  59. package/docs/archive/TRIGGER_RELEASE.md +0 -280
  60. package/docs/archive/VECTOR_INCLUDE_FIX.md +0 -129
  61. package/docs/archive/ota-and-status-enhancements.md +0 -911
  62. package/docs/archive/ota-status-architecture-diagrams.md +0 -658
  63. package/docs/archive/ota-status-quick-reference.md +0 -284
  64. package/docs/design/.gitkeep +0 -1
  65. package/docs/design/STATION_CREDENTIALS_DESIGN.md +0 -182
  66. package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +0 -71
  67. package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +0 -1011
  68. package/docs/development/DOCKER_TESTING.md +0 -196
  69. package/docs/development/PLATFORMIO_USAGE.md +0 -180
  70. package/docs/development/TESTING_SUMMARY.md +0 -126
  71. package/docs/development/contributing.md +0 -301
  72. package/docs/development/documentation.md +0 -583
  73. package/docs/features/DIAGNOSTICS_API.md +0 -534
  74. package/docs/implementation/BRIDGE_ARCHITECTURE_IMPLEMENTATION.md +0 -340
  75. package/docs/implementation/BRIDGE_HEALTH_MONITORING_IMPLEMENTATION.md +0 -213
  76. package/docs/implementation/BRIDGE_STATUS_FEATURE.md +0 -635
  77. package/docs/implementation/DIAGNOSTICS_API_IMPLEMENTATION.md +0 -232
  78. package/docs/implementation/IMPLEMENTATION_COMPLETE.md +0 -228
  79. package/docs/implementation/IMPLEMENTATION_NTP_TIME_SYNC.md +0 -325
  80. package/docs/implementation/IMPLEMENTATION_SUMMARY.md +0 -316
  81. package/docs/implementation/MESSAGE_QUEUE_IMPLEMENTATION.md +0 -405
  82. package/docs/implementation/MULTI_BRIDGE_IMPLEMENTATION.md +0 -520
  83. package/docs/implementation/NTP_TIME_SYNC_FEATURE.md +0 -392
  84. package/docs/improvements/FUTURE_PROPOSALS.md +0 -1016
  85. package/docs/improvements/IMPLEMENTATION_HISTORY.md +0 -1091
  86. package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +0 -709
  87. package/docs/improvements/README.md +0 -212
  88. package/docs/internal/CUSTOM_AGENT_ANALYSIS.md +0 -391
  89. package/docs/internal/ISSUE_65_VERIFICATION.md +0 -947
  90. package/docs/internal/ISSUE_66_CLOSURE.md +0 -249
  91. package/docs/internal/ISSUE_66_STATUS.md +0 -316
  92. package/docs/internal/PR_SUMMARY.md +0 -315
  93. package/docs/internal/REVIEW_SUMMARY.md +0 -332
  94. package/docs/multi-bridge-setup.md +0 -1025
  95. package/docs/platformio-publishing.md +0 -255
  96. package/docs/platformio-setup-summary.md +0 -121
  97. package/docs/releases/ANNOUNCEMENT_v1.8.6.md +0 -63
  98. package/docs/releases/ANNOUNCEMENT_v1.8.7.md +0 -113
  99. package/docs/releases/BRIDGE_STATUS_SELF_REGISTRATION_FIX.md +0 -221
  100. package/docs/releases/FEATURE_HISTORY.md +0 -543
  101. package/docs/releases/GITHUB_RELEASE_v1.8.6.md +0 -71
  102. package/docs/releases/GITHUB_RELEASE_v1.8.7.md +0 -90
  103. package/docs/releases/PATCH_v1.7.2.md +0 -262
  104. package/docs/releases/PATCH_v1.7.3.md +0 -262
  105. package/docs/releases/PATCH_v1.7.4.md +0 -219
  106. package/docs/releases/PHASE1_SUMMARY.md +0 -246
  107. package/docs/releases/PHASE2_SUMMARY.md +0 -499
  108. package/docs/releases/PUBLISH_v1.8.0_INSTRUCTIONS.md +0 -163
  109. package/docs/releases/QUICK_START_RELEASES.md +0 -113
  110. package/docs/releases/RELEASE_CHECKLIST_1.8.10.md +0 -331
  111. package/docs/releases/RELEASE_CHECKLIST_1.8.9.md +0 -207
  112. package/docs/releases/RELEASE_CHECKLIST_v1.7.4.md +0 -253
  113. package/docs/releases/RELEASE_CHECKLIST_v1.7.5.md +0 -315
  114. package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +0 -389
  115. package/docs/releases/RELEASE_CHECKLIST_v1.8.0.md +0 -331
  116. package/docs/releases/RELEASE_CHECKLIST_v1.8.2.md +0 -309
  117. package/docs/releases/RELEASE_NOTES_1.7.0.md +0 -539
  118. package/docs/releases/RELEASE_NOTES_1.8.10.md +0 -239
  119. package/docs/releases/RELEASE_NOTES_1.8.9.md +0 -213
  120. package/docs/releases/RELEASE_NOTES_v1.8.0.md +0 -685
  121. package/docs/releases/RELEASE_NOTES_v1.8.1.md +0 -221
  122. package/docs/releases/RELEASE_NOTES_v1.8.2.md +0 -421
  123. package/docs/releases/RELEASE_NOTES_v1.8.3.md +0 -292
  124. package/docs/releases/RELEASE_NOTES_v1.8.4.md +0 -277
  125. package/docs/releases/RELEASE_NOTES_v1.8.6.md +0 -205
  126. package/docs/releases/RELEASE_NOTES_v1.8.7.md +0 -184
  127. package/docs/releases/RELEASE_PLAN_v1.7.6.md +0 -816
  128. package/docs/releases/RELEASE_SUMMARY_1.8.10.md +0 -193
  129. package/docs/releases/RELEASE_SUMMARY_v1.7.4.md +0 -276
  130. package/docs/releases/RELEASE_SUMMARY_v1.7.5.md +0 -322
  131. package/docs/releases/RELEASE_SUMMARY_v1.7.6.md +0 -436
  132. package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +0 -391
  133. package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +0 -523
  134. package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +0 -542
  135. package/docs/troubleshooting/ARDUINO_IDE_VERSION_FIX_SUMMARY.md +0 -229
  136. package/docs/troubleshooting/ARDUINO_LIBRARY_NAME_FIX.md +0 -197
  137. package/docs/troubleshooting/CRASH_QUICK_REF.md +0 -93
  138. package/docs/troubleshooting/ESP32_C6_COMPATIBILITY.md +0 -157
  139. package/docs/troubleshooting/FREERTOS_ASSERTION_FAILURE.md +0 -288
  140. package/docs/troubleshooting/FREERTOS_FIX_IMPLEMENTATION.md +0 -267
  141. package/docs/troubleshooting/NPM_PUBLISHING_ISSUE_SUMMARY.md +0 -110
  142. package/docs/troubleshooting/PAINLESSMESH_V1.7.4_COMPILATION_ISSUES.md +0 -547
  143. package/docs/troubleshooting/QUICK_FIX_FREERTOS.md +0 -164
  144. package/docs/troubleshooting/SENSOR_NODE_CONNECTION_CRASH.md +0 -264
  145. package/docs/troubleshooting/common-architecture-mistakes.md +0 -438
  146. package/docs/troubleshooting/internet-access-faq.md +0 -299
  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 -108
  197. package/examples/multi_bridge/regular_node.ino +0 -141
  198. package/examples/multi_bridge/secondary_bridge.ino +0 -123
  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_