@alteriom/painlessmesh 1.6.1 → 1.7.2

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 (129) hide show
  1. package/CHANGELOG.md +380 -143
  2. package/LICENSE +674 -674
  3. package/README.md +477 -434
  4. package/RELEASE_GUIDE.md +504 -418
  5. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +175 -175
  6. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +1062 -0
  7. package/docs/MESH_TOPOLOGY_GUIDE.md +992 -0
  8. package/docs/MESH_TOPOLOGY_PROGRESS.md +422 -0
  9. package/docs/MQTT_BRIDGE_COMMANDS.md +894 -0
  10. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +324 -0
  11. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +576 -0
  12. package/docs/MQTT_SCHEMA_COMPLIANCE.md +285 -0
  13. package/docs/MQTT_SCHEMA_PROPOSALS.md +446 -0
  14. package/docs/MQTT_SCHEMA_REVIEW.md +690 -0
  15. package/docs/OTA_COMMANDS_REFERENCE.md +554 -0
  16. package/docs/PHASE1_GUIDE.md +349 -0
  17. package/docs/PHASE2_GUIDE.md +543 -0
  18. package/docs/README.md +77 -70
  19. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +222 -0
  20. package/docs/alteriom/overview.md +507 -507
  21. package/docs/api/core-api.md +606 -606
  22. package/docs/architecture/mesh-architecture.md +378 -378
  23. package/docs/architecture/plugin-system.md +516 -516
  24. package/docs/getting-started/first-mesh.md +409 -409
  25. package/docs/getting-started/installation.md +274 -274
  26. package/docs/getting-started/quickstart.md +157 -157
  27. package/docs/improvements/FEATURE_PROPOSALS.md +337 -0
  28. package/docs/improvements/PHASE1_IMPLEMENTATION.md +325 -0
  29. package/docs/improvements/PHASE2_IMPLEMENTATION.md +567 -0
  30. package/docs/improvements/README.md +86 -68
  31. package/docs/improvements/ota-and-status-enhancements.md +911 -0
  32. package/docs/improvements/ota-status-architecture-diagrams.md +658 -0
  33. package/docs/improvements/ota-status-quick-reference.md +284 -0
  34. package/docs/platformio-publishing.md +255 -0
  35. package/docs/platformio-setup-summary.md +121 -0
  36. package/docs/troubleshooting/common-issues.md +520 -520
  37. package/docs/troubleshooting/faq.md +472 -472
  38. package/docs/tutorials/basic-examples.md +717 -717
  39. package/docs/wiki/API-Reference.md +245 -245
  40. package/docs/wiki/Complete-Documentation.md +122 -122
  41. package/examples/alteriom/README.md +139 -81
  42. package/examples/alteriom/alteriom.ino +186 -185
  43. package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
  44. package/examples/alteriom/platformio.ini +24 -24
  45. package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
  46. package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
  47. package/examples/alteriomImproved/platformio.ini +25 -0
  48. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
  49. package/examples/alteriomPhase1/phase1_features.ino +242 -0
  50. package/examples/alteriomPhase1/platformio.ini +25 -0
  51. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
  52. package/examples/alteriomPhase2/phase2_features.ino +186 -0
  53. package/examples/alteriomPhase2/platformio.ini +25 -0
  54. package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
  55. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
  56. package/examples/alteriomSensorNode/platformio.ini +25 -0
  57. package/examples/basic/basic.ino +66 -66
  58. package/examples/basic/platformio.ini +25 -25
  59. package/examples/bridge/bridge.ino +51 -51
  60. package/examples/bridge/mesh_event_publisher.hpp +253 -0
  61. package/examples/bridge/mesh_topology_reporter.hpp +303 -0
  62. package/examples/bridge/mqtt_command_bridge.hpp +459 -0
  63. package/examples/bridge/mqtt_status_bridge.hpp +519 -0
  64. package/examples/bridge/platformio.ini +25 -25
  65. package/examples/echoNode/echoNode.ino +33 -33
  66. package/examples/echoNode/platformio.ini +25 -25
  67. package/examples/logClient/logClient.ino +109 -109
  68. package/examples/logClient/platformio.ini +25 -25
  69. package/examples/logServer/logServer.ino +81 -81
  70. package/examples/logServer/platformio.ini +25 -25
  71. package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
  72. package/examples/meshCommandNode/meshCommandNode.ino +263 -0
  73. package/examples/meshCommandNode/platformio.ini +25 -0
  74. package/examples/mqttBridge/mqttBridge.ino +118 -118
  75. package/examples/mqttBridge/platformio.ini +26 -26
  76. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
  77. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
  78. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
  79. package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
  80. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
  81. package/examples/mqttCommandBridge/platformio.ini +26 -0
  82. package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
  83. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
  84. package/examples/mqttStatusBridge/platformio.ini +26 -0
  85. package/examples/mqttTopologyTest/README.md +467 -0
  86. package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
  87. package/examples/mqttTopologyTest/platformio.ini +26 -0
  88. package/examples/namedMesh/namedMesh.ino +97 -97
  89. package/examples/namedMesh/platformio.ini +25 -25
  90. package/examples/otaReceiver/otaReceiver.ino +79 -79
  91. package/examples/otaReceiver/platformio.ini +25 -25
  92. package/examples/otaSender/otaSender.ino +160 -151
  93. package/examples/otaSender/platformio.ini +25 -25
  94. package/examples/startHere/platformio.ini +25 -25
  95. package/examples/startHere/startHere.ino +159 -159
  96. package/examples/webServer/platformio.ini +27 -27
  97. package/examples/webServer/webServer.ino +89 -89
  98. package/keywords.txt +48 -48
  99. package/library.json +55 -34
  100. package/library.properties +10 -10
  101. package/package.json +86 -78
  102. package/src/AlteriomPainlessMesh.h +97 -97
  103. package/src/arduino/wifi.hpp +365 -365
  104. package/src/boost/asynctcp.hpp +279 -279
  105. package/src/painlessMesh.h +70 -70
  106. package/src/painlessMeshSTA.cpp +236 -236
  107. package/src/painlessMeshSTA.h +58 -58
  108. package/src/painlessTaskOptions.h +4 -4
  109. package/src/painlessmesh/base64.hpp +111 -111
  110. package/src/painlessmesh/buffer.hpp +229 -229
  111. package/src/painlessmesh/callback.hpp +91 -91
  112. package/src/painlessmesh/configuration.hpp +77 -77
  113. package/src/painlessmesh/connection.hpp +192 -192
  114. package/src/painlessmesh/layout.hpp +188 -188
  115. package/src/painlessmesh/logger.hpp +158 -158
  116. package/src/painlessmesh/memory.hpp +119 -119
  117. package/src/painlessmesh/mesh.hpp +761 -560
  118. package/src/painlessmesh/metrics.hpp +322 -322
  119. package/src/painlessmesh/ntp.hpp +263 -263
  120. package/src/painlessmesh/ota.hpp +582 -553
  121. package/src/painlessmesh/plugin.hpp +188 -188
  122. package/src/painlessmesh/protocol.hpp +813 -813
  123. package/src/painlessmesh/router.hpp +322 -322
  124. package/src/painlessmesh/tcp.hpp +71 -71
  125. package/src/painlessmesh/validation.hpp +238 -238
  126. package/src/plugin/performance.hpp +214 -214
  127. package/src/plugin/remote.hpp +64 -64
  128. package/src/scheduler.cpp +10 -10
  129. package/src/wifi.cpp +2 -2
@@ -0,0 +1,894 @@
1
+ # MQTT Bridge Commands Reference
2
+
3
+ ## Overview
4
+
5
+ This document provides a complete reference for MQTT-to-mesh bridge commands in painlessMesh Alteriom fork. The MQTT bridge enables bidirectional communication between MQTT brokers and mesh networks, allowing web applications to control and monitor mesh nodes.
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Architecture Overview](#architecture-overview)
10
+ 2. [Command Types](#command-types)
11
+ 3. [MQTT Topic Structure](#mqtt-topic-structure)
12
+ 4. [Command Definitions](#command-definitions)
13
+ 5. [Implementation Guide](#implementation-guide)
14
+ 6. [Complete Examples](#complete-examples)
15
+ 7. [Troubleshooting](#troubleshooting)
16
+
17
+ ---
18
+
19
+ ## Architecture Overview
20
+
21
+ ### Communication Flow
22
+
23
+ ```
24
+ Web Application → MQTT Broker → Gateway Bridge → Mesh Network → Target Node
25
+ Target Node → Mesh Network → Gateway Bridge → MQTT Broker → Web Application
26
+ ```
27
+
28
+ ### Components
29
+
30
+ 1. **MQTT Broker** - Central message router (Mosquitto, HiveMQ, AWS IoT)
31
+ 2. **Gateway Bridge** - ESP32/ESP8266 with WiFi + mesh capability
32
+ 3. **Mesh Nodes** - ESP devices in mesh network
33
+ 4. **Web Application** - Control interface publishing MQTT commands
34
+
35
+ ### Message Types
36
+
37
+ | Direction | Package Type | Purpose |
38
+ |-----------|--------------|---------|
39
+ | MQTT → Mesh | CommandPackage (201) | Control device, request data |
40
+ | Mesh → MQTT | StatusPackage (202) | Report device status |
41
+ | Mesh → MQTT | SensorPackage (200) | Sensor data reports |
42
+ | Mesh → MQTT | EnhancedStatusPackage (203) | Detailed health metrics |
43
+
44
+ ---
45
+
46
+ ## Command Types
47
+
48
+ ### Device Control Commands (1-99)
49
+
50
+ | Command ID | Name | Description | Parameters |
51
+ |------------|------|-------------|------------|
52
+ | 1 | RESET | Restart device | None |
53
+ | 2 | SLEEP | Enter deep sleep | `duration_ms` (uint32_t) |
54
+ | 3 | WAKE | Wake from sleep | None |
55
+ | 10 | LED_CONTROL | Control onboard LED | `state` (bool), `brightness` (uint8_t) |
56
+ | 11 | RELAY_SWITCH | Control relay output | `channel` (uint8_t), `state` (bool) |
57
+ | 12 | PWM_SET | Set PWM output | `pin` (uint8_t), `duty` (uint16_t) |
58
+ | 20 | SENSOR_ENABLE | Enable/disable sensor | `sensor_id` (uint8_t), `enabled` (bool) |
59
+ | 21 | SENSOR_CALIBRATE | Calibrate sensor | `sensor_id` (uint8_t) |
60
+
61
+ ### Configuration Commands (100-199)
62
+
63
+ | Command ID | Name | Description | Parameters |
64
+ |------------|------|-------------|------------|
65
+ | 100 | GET_CONFIG | Request current configuration | None |
66
+ | 101 | SET_CONFIG | Update configuration | JSON config object |
67
+ | 102 | RESET_CONFIG | Reset to factory defaults | None |
68
+ | 103 | SAVE_CONFIG | Persist config to flash | None |
69
+ | 110 | SET_SAMPLE_RATE | Change sensor sample rate | `rate_ms` (uint32_t) |
70
+ | 111 | SET_DEVICE_NAME | Update device name | `name` (string) |
71
+
72
+ ### Status Commands (200-255)
73
+
74
+ | Command ID | Name | Description | Parameters |
75
+ |------------|------|-------------|------------|
76
+ | 200 | GET_STATUS | Request basic status | None |
77
+ | 201 | GET_METRICS | Request performance metrics | None |
78
+ | 202 | GET_DIAGNOSTICS | Request detailed diagnostics | None |
79
+ | 210 | START_MONITORING | Begin continuous monitoring | `interval_ms` (uint32_t) |
80
+ | 211 | STOP_MONITORING | Stop continuous monitoring | None |
81
+
82
+ ### Topology Commands (300-399) ✨ NEW in v0.5.0
83
+
84
+ | Command ID | Name | Description | Parameters |
85
+ |------------|------|-------------|------------|
86
+ | 300 | GET_TOPOLOGY | Request mesh network topology | `format` (optional): "full" or "summary" |
87
+
88
+ **Response:** Full mesh topology published to `alteriom/mesh/{mesh_id}/topology/response` with `correlation_id` field matching the command ID.
89
+
90
+ **Example Response:**
91
+ ```json
92
+ {
93
+ "schema_version": 1,
94
+ "event": "mesh_topology",
95
+ "correlation_id": "12345",
96
+ "mesh_id": "MESH-001",
97
+ "nodes": [...],
98
+ "connections": [...],
99
+ "metrics": {...}
100
+ }
101
+ ```
102
+
103
+ ---
104
+
105
+ ## MQTT Topic Structure
106
+
107
+ ### Command Topics (Published by Web App)
108
+
109
+ ```
110
+ mesh/command/{nodeId} # Send command to specific node
111
+ mesh/command/broadcast # Broadcast command to all nodes
112
+ mesh/config/{nodeId}/get # Request configuration
113
+ mesh/config/{nodeId}/set # Update configuration
114
+ mesh/ota/{nodeId}/start # Initiate OTA update
115
+ ```
116
+
117
+ ### Response Topics (Published by Gateway Bridge)
118
+
119
+ ```
120
+ mesh/response/{nodeId} # Command acknowledgments
121
+ mesh/status/{nodeId} # Status updates (Type 202)
122
+ mesh/sensor/{nodeId} # Sensor data (Type 200)
123
+ mesh/health/{nodeId} # Enhanced status (Type 203)
124
+ mesh/config/{nodeId} # Configuration data
125
+ mesh/error/{nodeId} # Error reports
126
+ ```
127
+
128
+ ### System Topics (Legacy - v0.4.0)
129
+
130
+ ```
131
+ mesh/gateway/status # Gateway bridge health
132
+ mesh/topology # Mesh network topology (old format)
133
+ mesh/nodes # List of connected nodes
134
+ ```
135
+
136
+ ### Topology & Event Topics ✨ NEW (v0.5.0 - @alteriom/mqtt-schema compliant)
137
+
138
+ ```
139
+ alteriom/mesh/{mesh_id}/topology # Full/incremental mesh topology
140
+ alteriom/mesh/{mesh_id}/topology/response # Topology responses to GET_TOPOLOGY command
141
+ alteriom/mesh/{mesh_id}/events # Real-time mesh state change events
142
+ ```
143
+
144
+ **Schema Compliance:** All topology and event messages conform to **@alteriom/mqtt-schema v0.5.0** specification.
145
+
146
+ **Key Features:**
147
+ - **Device ID Format:** `ALT-XXXXXXXXXXXX` (12 hex digits)
148
+ - **Envelope Fields:** `schema_version`, `device_id`, `device_type`, `timestamp`, `firmware_version`
149
+ - **Connection Metrics:** RSSI, latency, quality (0-100), packet counts
150
+ - **Network Metrics:** Total nodes, network diameter, average quality
151
+ - **Update Types:** Full (every 60s), Incremental (every 5s if changed)
152
+ - **Event Types:** node_join, node_leave, connection_lost, connection_restored, network_split, network_merged
153
+
154
+ ---
155
+
156
+ ## Command Definitions
157
+
158
+ ### CommandPackage Structure (Type 201)
159
+
160
+ Defined in `examples/alteriom/alteriom_sensor_package.hpp`:
161
+
162
+ ```cpp
163
+ class CommandPackage : public painlessmesh::plugin::SinglePackage {
164
+ public:
165
+ uint8_t command = 0; // Command ID (1-255)
166
+ uint32_t targetDevice = 0; // Destination node ID
167
+ uint32_t commandId = 0; // Unique command tracking ID
168
+ TSTRING parameters = ""; // JSON-encoded parameters
169
+
170
+ CommandPackage() : SinglePackage(201) {}
171
+ };
172
+ ```
173
+
174
+ ### Command Parameter Encoding
175
+
176
+ Parameters are JSON-encoded strings:
177
+
178
+ ```json
179
+ {
180
+ "state": "ON",
181
+ "brightness": 75,
182
+ "duration_ms": 5000
183
+ }
184
+ ```
185
+
186
+ ### Command Response Structure
187
+
188
+ Responses use StatusPackage (Type 202) with enhanced fields:
189
+
190
+ ```cpp
191
+ class StatusPackage : public painlessmesh::plugin::BroadcastPackage {
192
+ public:
193
+ uint8_t deviceStatus = 0; // 0=OK, 1=Warning, 2=Error
194
+ uint32_t uptime = 0; // Seconds since boot
195
+ uint16_t freeMemory = 0; // Free heap in KB
196
+ TSTRING firmwareVersion = ""; // Current firmware version
197
+
198
+ // Response fields
199
+ uint32_t responseToCommand = 0; // Original commandId
200
+ TSTRING responseMessage = ""; // Success/error message
201
+
202
+ StatusPackage() : BroadcastPackage(202) {}
203
+ };
204
+ ```
205
+
206
+ ---
207
+
208
+ ## Implementation Guide
209
+
210
+ ### Gateway Bridge Implementation
211
+
212
+ The gateway bridge is implemented in `examples/bridge/mqtt_command_bridge.hpp` and provides:
213
+
214
+ 1. **MQTT → Mesh Command Forwarding**
215
+ - Subscribes to command topics
216
+ - Parses JSON payloads
217
+ - Routes commands to target nodes
218
+
219
+ 2. **Mesh → MQTT Response Forwarding**
220
+ - Receives mesh messages
221
+ - Publishes to appropriate MQTT topics
222
+ - Maintains message routing
223
+
224
+ 3. **Configuration Management**
225
+ - Handles config requests
226
+ - Applies config updates
227
+ - Sends acknowledgments
228
+
229
+ 4. **Local Command Execution**
230
+ - Executes commands targeted at gateway
231
+ - Sends responses via MQTT
232
+
233
+ ### Mesh Node Implementation
234
+
235
+ Mesh nodes implement command handlers in `examples/alteriom/mesh_command_node.ino`:
236
+
237
+ 1. **Command Reception**
238
+ - Listen for CommandPackage (Type 201)
239
+ - Parse command and parameters
240
+ - Execute appropriate action
241
+
242
+ 2. **Response Generation**
243
+ - Create StatusPackage response
244
+ - Include commandId for tracking
245
+ - Broadcast back to mesh
246
+
247
+ 3. **Status Reporting**
248
+ - Send periodic status updates
249
+ - Report errors and warnings
250
+ - Include relevant metrics
251
+
252
+ ---
253
+
254
+ ## Mesh Topology Reporting ✨ NEW in v0.5.0
255
+
256
+ ### Overview
257
+
258
+ The mesh topology system provides real-time visibility into the structure and health of your mesh network. It publishes detailed information about nodes, connections, and network metrics in a standardized format that complies with **@alteriom/mqtt-schema v0.5.0**.
259
+
260
+ **Implementation:** `examples/bridge/mesh_topology_reporter.hpp`
261
+
262
+ ### Topology Message Structure
263
+
264
+ #### Envelope Fields (Required by @alteriom/mqtt-schema)
265
+
266
+ ```json
267
+ {
268
+ "schema_version": 1,
269
+ "device_id": "ALT-6825DD341CA4",
270
+ "device_type": "gateway",
271
+ "timestamp": "2025-01-12T15:00:00Z",
272
+ "firmware_version": "GW 2.3.4"
273
+ }
274
+ ```
275
+
276
+ #### Topology Payload
277
+
278
+ ```json
279
+ {
280
+ "event": "mesh_topology",
281
+ "mesh_id": "MESH-001",
282
+ "gateway_node_id": "ALT-6825DD341CA4",
283
+ "nodes": [
284
+ {
285
+ "node_id": "ALT-6825DD341CA4",
286
+ "role": "gateway",
287
+ "status": "online",
288
+ "last_seen": "2025-01-12T15:00:00Z",
289
+ "firmware_version": "GW 2.3.4",
290
+ "uptime_seconds": 86400,
291
+ "free_memory_kb": 128,
292
+ "connection_count": 3
293
+ }
294
+ ],
295
+ "connections": [
296
+ {
297
+ "from_node": "ALT-6825DD341CA4",
298
+ "to_node": "ALT-441D64F804A0",
299
+ "quality": 95,
300
+ "latency_ms": 12,
301
+ "rssi": -42,
302
+ "hop_count": 1
303
+ }
304
+ ],
305
+ "metrics": {
306
+ "total_nodes": 4,
307
+ "online_nodes": 4,
308
+ "network_diameter": 2,
309
+ "avg_connection_quality": 85,
310
+ "messages_per_second": 12.4
311
+ },
312
+ "update_type": "full"
313
+ }
314
+ ```
315
+
316
+ ### Publishing Schedule
317
+
318
+ | Update Type | Frequency | Trigger | Topic |
319
+ |-------------|-----------|---------|-------|
320
+ | Full Topology | Every 60 seconds | Timer | `alteriom/mesh/MESH-001/topology` |
321
+ | Incremental | Every 5 seconds | Change detection | `alteriom/mesh/MESH-001/topology` |
322
+ | On-Demand | Immediate | GET_TOPOLOGY command | `alteriom/mesh/MESH-001/topology/response` |
323
+
324
+ ### Node Roles
325
+
326
+ | Role | Description | Typical Use |
327
+ |------|-------------|-------------|
328
+ | gateway | MQTT bridge with WiFi | Root node, MQTT publisher |
329
+ | sensor | Sensor measurement node | Data collection |
330
+ | repeater | Range extender | Network coverage |
331
+
332
+ ### Connection Quality Metrics
333
+
334
+ **Quality Score (0-100):** Calculated from latency, packet loss, and RSSI
335
+
336
+ - **90-100:** Excellent - Low latency (<50ms), strong signal (>-50 dBm)
337
+ - **70-89:** Good - Moderate latency (<100ms), good signal (>-70 dBm)
338
+ - **50-69:** Fair - Higher latency (<200ms), weaker signal (>-80 dBm)
339
+ - **0-49:** Poor - High latency (>200ms), weak signal (<-80 dBm)
340
+
341
+ **RSSI (Received Signal Strength Indicator):**
342
+ - Values in dBm (negative numbers)
343
+ - Stronger signal = higher (less negative) value
344
+ - Example: -42 dBm is better than -75 dBm
345
+
346
+ **Latency:**
347
+ - Round-trip time in milliseconds
348
+ - Calculated from message exchange timing
349
+ - Lower is better
350
+
351
+ ### GET_TOPOLOGY Command (300)
352
+
353
+ **Request:** Publish to `mesh/command/{gateway_id}` or `mesh/command/broadcast`
354
+
355
+ ```json
356
+ {
357
+ "type": 201,
358
+ "command": 300,
359
+ "targetDevice": 0,
360
+ "commandId": 12345,
361
+ "parameters": "{}"
362
+ }
363
+ ```
364
+
365
+ **Response:** Published to `alteriom/mesh/MESH-001/topology/response`
366
+
367
+ ```json
368
+ {
369
+ "schema_version": 1,
370
+ "device_id": "ALT-6825DD341CA4",
371
+ "event": "mesh_topology",
372
+ "correlation_id": "12345",
373
+ "mesh_id": "MESH-001",
374
+ ... full topology ...
375
+ }
376
+ ```
377
+
378
+ **Key Feature:** The `correlation_id` field matches the command's `commandId` for request tracking.
379
+
380
+ ---
381
+
382
+ ## Mesh Events ✨ NEW in v0.5.0
383
+
384
+ ### Overview
385
+
386
+ Real-time notifications of mesh network state changes. Published immediately when events occur.
387
+
388
+ **Implementation:** `examples/bridge/mesh_event_publisher.hpp`
389
+ **Topic:** `alteriom/mesh/MESH-001/events`
390
+
391
+ ### Event Types
392
+
393
+ | Event Type | Description | When Triggered |
394
+ |------------|-------------|----------------|
395
+ | node_join | New node connected | onNewConnection() callback |
396
+ | node_leave | Node disconnected | onDroppedConnection() callback |
397
+ | connection_lost | Direct connection failed | Connection timeout |
398
+ | connection_restored | Connection recovered | After connection_lost |
399
+ | network_split | Mesh partitioned | Network segmentation detected |
400
+ | network_merged | Partitions rejoined | Segments reconnected |
401
+
402
+ ### Event Message Structure
403
+
404
+ #### Node Join Event
405
+
406
+ ```json
407
+ {
408
+ "schema_version": 1,
409
+ "device_id": "ALT-6825DD341CA4",
410
+ "device_type": "gateway",
411
+ "timestamp": "2025-01-12T15:05:00Z",
412
+ "firmware_version": "GW 2.3.4",
413
+ "event": "mesh_event",
414
+ "event_type": "node_join",
415
+ "mesh_id": "MESH-001",
416
+ "affected_nodes": ["ALT-441D64F804A0"],
417
+ "details": {
418
+ "total_nodes": 4,
419
+ "timestamp": "2025-01-12T15:05:00Z"
420
+ }
421
+ }
422
+ ```
423
+
424
+ #### Node Leave Event
425
+
426
+ ```json
427
+ {
428
+ "schema_version": 1,
429
+ "device_id": "ALT-6825DD341CA4",
430
+ "device_type": "gateway",
431
+ "timestamp": "2025-01-12T15:10:00Z",
432
+ "firmware_version": "GW 2.3.4",
433
+ "event": "mesh_event",
434
+ "event_type": "node_leave",
435
+ "mesh_id": "MESH-001",
436
+ "affected_nodes": ["ALT-441D64F804A0"],
437
+ "details": {
438
+ "reason": "connection_lost",
439
+ "last_seen": "2025-01-12T15:08:45Z",
440
+ "total_nodes": 3
441
+ }
442
+ }
443
+ ```
444
+
445
+ #### Connection Lost Event
446
+
447
+ ```json
448
+ {
449
+ "event": "mesh_event",
450
+ "event_type": "connection_lost",
451
+ "affected_nodes": ["ALT-441D64F804A0"],
452
+ "details": {
453
+ "reason": "timeout",
454
+ "timestamp": "2025-01-12T15:10:00Z"
455
+ }
456
+ }
457
+ ```
458
+
459
+ ### Integration with Web Dashboards
460
+
461
+ **Subscribe to events:**
462
+
463
+ ```javascript
464
+ const mqtt = require('mqtt');
465
+ const client = mqtt.connect('mqtt://broker.local:1883');
466
+
467
+ client.subscribe('alteriom/mesh/+/events');
468
+ client.subscribe('alteriom/mesh/+/topology');
469
+
470
+ client.on('message', (topic, message) => {
471
+ const data = JSON.parse(message.toString());
472
+
473
+ if (data.event === 'mesh_event') {
474
+ switch (data.event_type) {
475
+ case 'node_join':
476
+ console.log(`✅ Node joined: ${data.affected_nodes[0]}`);
477
+ break;
478
+ case 'node_leave':
479
+ console.log(`⚠️ Node left: ${data.affected_nodes[0]}`);
480
+ break;
481
+ }
482
+ }
483
+
484
+ if (data.event === 'mesh_topology') {
485
+ console.log(`📊 Topology update: ${data.nodes.length} nodes`);
486
+ // Render network graph with D3.js or similar
487
+ }
488
+ });
489
+ ```
490
+
491
+ **Python example:**
492
+
493
+ ```python
494
+ import paho.mqtt.client as mqtt
495
+ import json
496
+
497
+ def on_message(client, userdata, msg):
498
+ data = json.loads(msg.payload.decode())
499
+
500
+ if data['event'] == 'mesh_event':
501
+ event_type = data['event_type']
502
+ nodes = data['affected_nodes']
503
+ print(f"Event: {event_type} - Nodes: {nodes}")
504
+
505
+ elif data['event'] == 'mesh_topology':
506
+ total_nodes = data['metrics']['total_nodes']
507
+ quality = data['metrics']['avg_connection_quality']
508
+ print(f"Topology: {total_nodes} nodes, quality: {quality}%")
509
+
510
+ client = mqtt.Client()
511
+ client.on_message = on_message
512
+ client.connect("broker.local", 1883)
513
+ client.subscribe("alteriom/mesh/+/events")
514
+ client.subscribe("alteriom/mesh/+/topology")
515
+ client.loop_forever()
516
+ ```
517
+
518
+ ---
519
+
520
+ ## Complete Examples
521
+
522
+ ### Example 1: Send LED Control Command via MQTT
523
+
524
+ **Publish to:** `mesh/command/123456`
525
+
526
+ ```json
527
+ {
528
+ "type": 201,
529
+ "command": 10,
530
+ "targetDevice": 123456,
531
+ "commandId": 1001,
532
+ "parameters": "{\"state\":true,\"brightness\":75}"
533
+ }
534
+ ```
535
+
536
+ **Expected Response on:** `mesh/response/123456`
537
+
538
+ ```json
539
+ {
540
+ "type": 202,
541
+ "from": 123456,
542
+ "deviceStatus": 0,
543
+ "uptime": 3600,
544
+ "freeMemory": 45,
545
+ "firmwareVersion": "1.0.0",
546
+ "responseToCommand": 1001,
547
+ "responseMessage": "LED ON"
548
+ }
549
+ ```
550
+
551
+ ### Example 2: Broadcast Configuration Request
552
+
553
+ **Publish to:** `mesh/command/broadcast`
554
+
555
+ ```json
556
+ {
557
+ "type": 201,
558
+ "command": 100,
559
+ "targetDevice": 0,
560
+ "commandId": 2001,
561
+ "parameters": "{}"
562
+ }
563
+ ```
564
+
565
+ All nodes respond with their configuration on respective `mesh/config/<nodeId>` topics.
566
+
567
+ ### Example 3: Update Node Configuration
568
+
569
+ **Publish to:** `mesh/config/123456/set`
570
+
571
+ ```json
572
+ {
573
+ "config": {
574
+ "deviceName": "Sensor-Living-Room",
575
+ "sampleRate": 30000,
576
+ "ledEnabled": false
577
+ }
578
+ }
579
+ ```
580
+
581
+ **Expected Response on:** `mesh/response/123456`
582
+
583
+ ```json
584
+ {
585
+ "status": "success",
586
+ "device_id": "123456",
587
+ "message": "Configuration updated"
588
+ }
589
+ ```
590
+
591
+ ### Example 4: Request Device Status
592
+
593
+ **Publish to:** `mesh/command/123456`
594
+
595
+ ```json
596
+ {
597
+ "type": 201,
598
+ "command": 200,
599
+ "targetDevice": 123456,
600
+ "commandId": 3001,
601
+ "parameters": "{}"
602
+ }
603
+ ```
604
+
605
+ **Expected Response on:** `mesh/status/123456`
606
+
607
+ ```json
608
+ {
609
+ "type": 202,
610
+ "from": 123456,
611
+ "deviceStatus": 0,
612
+ "uptime": 7200,
613
+ "freeMemory": 42,
614
+ "firmwareVersion": "1.0.0",
615
+ "responseToCommand": 3001,
616
+ "responseMessage": "OK"
617
+ }
618
+ ```
619
+
620
+ ---
621
+
622
+ ## Using with Web Applications
623
+
624
+ ### JavaScript/Node.js Example
625
+
626
+ ```javascript
627
+ const mqtt = require('mqtt');
628
+ const client = mqtt.connect('mqtt://192.168.1.100:1883');
629
+
630
+ client.on('connect', () => {
631
+ console.log('Connected to MQTT broker');
632
+
633
+ // Subscribe to response topics
634
+ client.subscribe('mesh/response/#');
635
+ client.subscribe('mesh/status/#');
636
+
637
+ // Send LED control command
638
+ const command = {
639
+ type: 201,
640
+ command: 10,
641
+ targetDevice: 123456,
642
+ commandId: Date.now(),
643
+ parameters: JSON.stringify({
644
+ state: true,
645
+ brightness: 75
646
+ })
647
+ };
648
+
649
+ client.publish('mesh/command/123456', JSON.stringify(command));
650
+ });
651
+
652
+ client.on('message', (topic, message) => {
653
+ console.log(`Received on ${topic}:`, message.toString());
654
+ const response = JSON.parse(message.toString());
655
+
656
+ if (response.responseToCommand) {
657
+ console.log(`Command ${response.responseToCommand} result: ${response.responseMessage}`);
658
+ }
659
+ });
660
+ ```
661
+
662
+ ### Python Example
663
+
664
+ ```python
665
+ import paho.mqtt.client as mqtt
666
+ import json
667
+ import time
668
+
669
+ def on_connect(client, userdata, flags, rc):
670
+ print(f"Connected with result code {rc}")
671
+ client.subscribe("mesh/response/#")
672
+ client.subscribe("mesh/status/#")
673
+
674
+ # Send LED control command
675
+ command = {
676
+ "type": 201,
677
+ "command": 10,
678
+ "targetDevice": 123456,
679
+ "commandId": int(time.time() * 1000),
680
+ "parameters": json.dumps({
681
+ "state": True,
682
+ "brightness": 75
683
+ })
684
+ }
685
+
686
+ client.publish("mesh/command/123456", json.dumps(command))
687
+
688
+ def on_message(client, userdata, msg):
689
+ print(f"Received on {msg.topic}: {msg.payload.decode()}")
690
+ response = json.loads(msg.payload.decode())
691
+
692
+ if "responseToCommand" in response:
693
+ print(f"Command {response['responseToCommand']} result: {response['responseMessage']}")
694
+
695
+ client = mqtt.Client()
696
+ client.on_connect = on_connect
697
+ client.on_message = on_message
698
+
699
+ client.connect("192.168.1.100", 1883, 60)
700
+ client.loop_forever()
701
+ ```
702
+
703
+ ---
704
+
705
+ ## Troubleshooting
706
+
707
+ ### Commands Not Reaching Nodes
708
+
709
+ **Symptoms:**
710
+ - Commands published to MQTT but nodes don't respond
711
+ - No error messages in gateway logs
712
+
713
+ **Solutions:**
714
+ 1. **Check MQTT Connection**: Verify bridge is connected to broker
715
+ ```cpp
716
+ if (mqttClient.connected()) {
717
+ Serial.println("MQTT connected");
718
+ }
719
+ ```
720
+
721
+ 2. **Verify Topic Format**: Ensure exact topic structure with nodeId
722
+ ```
723
+ Correct: mesh/command/123456
724
+ Wrong: mesh/commands/123456
725
+ Wrong: mesh/command/0x1E240
726
+ ```
727
+
728
+ 3. **Check JSON Format**: Validate command payload structure
729
+ ```bash
730
+ # Use mosquitto_pub to test
731
+ mosquitto_pub -h 192.168.1.100 -t "mesh/command/123456" -m '{"type":201,"command":10,"targetDevice":123456,"commandId":1001,"parameters":"{}"}'
732
+ ```
733
+
734
+ 4. **Inspect Mesh Connectivity**: Use `mesh.getNodeList()` to verify nodes
735
+ ```cpp
736
+ auto nodes = mesh.getNodeList();
737
+ Serial.printf("Connected nodes: %d\n", nodes.size());
738
+ ```
739
+
740
+ 5. **Enable Debug Logging**:
741
+ ```cpp
742
+ mesh.setDebugMsgTypes(ERROR | CONNECTION | COMMUNICATION);
743
+ ```
744
+
745
+ ### No Response from Nodes
746
+
747
+ **Symptoms:**
748
+ - Commands reach nodes but no response received
749
+ - Node serial shows command execution but no MQTT response
750
+
751
+ **Solutions:**
752
+ 1. **Verify Command Handler**: Ensure nodes have command handler implemented
753
+ 2. **Check Command ID**: Confirm command ID is supported by node
754
+ 3. **Monitor Serial Output**: Check node serial for command reception
755
+ 4. **Validate Parameters**: Ensure parameter JSON is valid
756
+ 5. **Check Response Routing**: Verify responses are reaching gateway
757
+
758
+ ### MQTT Broker Issues
759
+
760
+ **Symptoms:**
761
+ - Gateway can't connect to broker
762
+ - Messages not being delivered
763
+
764
+ **Solutions:**
765
+ 1. **Connection Refused**: Check broker IP, port, credentials
766
+ ```cpp
767
+ mqttClient.setServer(MQTT_BROKER_IP, MQTT_BROKER_PORT);
768
+ if (!mqttClient.connect("painlessMesh-gateway")) {
769
+ Serial.printf("MQTT error: %d\n", mqttClient.state());
770
+ }
771
+ ```
772
+
773
+ 2. **Topic Not Found**: Verify subscription before publishing
774
+ ```cpp
775
+ // Subscribe first
776
+ mqtt.subscribe("mesh/command/#");
777
+ delay(100);
778
+ // Then publish
779
+ mqtt.publish("mesh/response/123", "test");
780
+ ```
781
+
782
+ 3. **QoS Issues**: Use QoS 1 for reliable delivery
783
+ ```cpp
784
+ mqtt.publish(topic, payload, true); // retained = true
785
+ ```
786
+
787
+ 4. **Retained Messages**: Clear retained messages if needed
788
+ ```bash
789
+ mosquitto_pub -h 192.168.1.100 -t "mesh/command/123456" -n -r
790
+ ```
791
+
792
+ ### Memory Issues
793
+
794
+ **Symptoms:**
795
+ - Gateway crashes or reboots unexpectedly
796
+ - Commands work initially but fail after time
797
+
798
+ **Solutions:**
799
+ 1. **Monitor Heap**: Check free memory regularly
800
+ ```cpp
801
+ Serial.printf("Free heap: %d\n", ESP.getFreeHeap());
802
+ ```
803
+
804
+ 2. **Optimize JSON Buffer Size**: Use appropriate buffer sizes
805
+ ```cpp
806
+ // Too large wastes memory
807
+ DynamicJsonDocument doc(1024); // Adjust based on needs
808
+ ```
809
+
810
+ 3. **Clean Up Objects**: Delete unused objects
811
+ ```cpp
812
+ delete commandBridge; // If recreating
813
+ ```
814
+
815
+ 4. **Reduce Debug Output**: Disable verbose logging in production
816
+
817
+ ### Network Stability
818
+
819
+ **Symptoms:**
820
+ - Intermittent command delivery
821
+ - Nodes dropping from mesh
822
+
823
+ **Solutions:**
824
+ 1. **Check WiFi Signal**: Ensure strong WiFi for gateway
825
+ 2. **Reduce Mesh Traffic**: Space out command sends
826
+ 3. **Use Exponential Backoff**: Retry failed commands with delay
827
+ 4. **Monitor Mesh Health**: Track connection changes
828
+
829
+ ---
830
+
831
+ ## Best Practices
832
+
833
+ ### Command Design
834
+
835
+ 1. **Use Unique Command IDs**: Generate unique IDs for tracking
836
+ ```cpp
837
+ cmd.commandId = millis() | (nodeId << 16);
838
+ ```
839
+
840
+ 2. **Keep Parameters Small**: Minimize JSON parameter size
841
+ ```json
842
+ Good: {"s":1,"b":75}
843
+ Avoid: {"state":"enabled","brightness_level":75,"extra_field":"unused"}
844
+ ```
845
+
846
+ 3. **Implement Timeouts**: Don't wait indefinitely for responses
847
+ ```javascript
848
+ const timeout = setTimeout(() => {
849
+ console.log('Command timeout');
850
+ }, 5000);
851
+ ```
852
+
853
+ 4. **Handle Failures Gracefully**: Retry important commands
854
+ ```javascript
855
+ let retries = 3;
856
+ function sendCommand() {
857
+ client.publish(topic, command);
858
+ setTimeout(() => {
859
+ if (!responseReceived && retries-- > 0) {
860
+ sendCommand();
861
+ }
862
+ }, 2000);
863
+ }
864
+ ```
865
+
866
+ ### Security Considerations
867
+
868
+ 1. **Use Authentication**: Enable MQTT broker authentication
869
+ 2. **Validate Commands**: Check command bounds and parameters
870
+ 3. **Rate Limiting**: Limit command frequency per client
871
+ 4. **Access Control**: Restrict sensitive commands
872
+ 5. **Encryption**: Use TLS for production MQTT connections
873
+
874
+ ### Performance Optimization
875
+
876
+ 1. **Batch Commands**: Group related commands when possible
877
+ 2. **Cache Configuration**: Avoid repeated config requests
878
+ 3. **Use Broadcast Sparingly**: Unicast when targeting specific nodes
879
+ 4. **Monitor Latency**: Track command response times
880
+
881
+ ---
882
+
883
+ ## Related Documentation
884
+
885
+ - [OTA Commands Reference](OTA_COMMANDS_REFERENCE.md) - Firmware update commands
886
+ - [API Reference](api/core-api.md) - Core painlessMesh API
887
+ - [Plugin System](architecture/plugin-system.md) - Custom package development
888
+ - [Alteriom Overview](alteriom/overview.md) - Alteriom package types
889
+
890
+ ---
891
+
892
+ **Last Updated:** October 2025
893
+ **painlessMesh Version:** 1.7.0+ Alteriom Fork
894
+ **Author:** Alteriom Development Team