@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,554 +0,0 @@
1
- # OTA Commands and API Reference
2
-
3
- ## Overview
4
-
5
- This document provides a complete reference for OTA (Over-The-Air) firmware update commands in painlessMesh, including Phase 2 broadcast mode enhancements and Alteriom MQTT schema compliance for firmware status reporting.
6
-
7
- ## Table of Contents
8
-
9
- 1. [OTA Command API](#ota-command-api)
10
- 2. [Broadcast OTA (Phase 2)](#broadcast-ota-phase-2)
11
- 3. [Firmware Status Reporting](#firmware-status-reporting)
12
- 4. [MQTT Schema Compliance](#mqtt-schema-compliance)
13
- 5. [Complete Examples](#complete-examples)
14
- 6. [Troubleshooting](#troubleshooting)
15
-
16
- ---
17
-
18
- ## OTA Command API
19
-
20
- ### mesh.offerOTA()
21
-
22
- Announce and distribute firmware updates to mesh nodes.
23
-
24
- ```cpp
25
- std::shared_ptr<Task> offerOTA(
26
- TSTRING role,
27
- TSTRING hardware,
28
- TSTRING md5,
29
- size_t noPart,
30
- bool forced = false,
31
- bool broadcasted = false, // Phase 2 feature
32
- bool compressed = false // Phase 1 feature
33
- )
34
- ```
35
-
36
- #### Parameters
37
-
38
- | Parameter | Type | Description | Default |
39
- |-----------|------|-------------|---------|
40
- | `role` | TSTRING | Target node role (e.g., "sensor", "gateway") | Required |
41
- | `hardware` | TSTRING | Hardware type: "ESP32" or "ESP8266" | Required |
42
- | `md5` | TSTRING | MD5 hash of firmware binary for version checking | Required |
43
- | `noPart` | size_t | Total number of firmware chunks | Required |
44
- | `forced` | bool | Force update even if MD5 matches current version | false |
45
- | `broadcasted` | bool | **[Phase 2]** Enable broadcast distribution mode | false |
46
- | `compressed` | bool | [Phase 1] Enable compression (40-60% bandwidth savings) | false |
47
-
48
- #### Returns
49
-
50
- `std::shared_ptr<Task>` - Shared pointer to task managing OTA announcements
51
-
52
- #### Behavior
53
-
54
- **Unicast Mode (broadcasted=false):**
55
- - Each node requests chunks individually
56
- - Root node responds to each request
57
- - Network traffic: O(N × F) where N=nodes, F=firmware size
58
- - Best for: 1-10 nodes
59
-
60
- **Broadcast Mode (broadcasted=true):**
61
- - Root node broadcasts chunks once
62
- - All nodes receive simultaneously
63
- - Network traffic: O(F) - independent of node count
64
- - Best for: 10-100+ nodes
65
- - ~98% traffic reduction for 50-node mesh
66
-
67
- #### Example
68
-
69
- ```cpp
70
- // Phase 2 Broadcast OTA with compression
71
- auto otaTask = mesh.offerOTA(
72
- "sensor", // Role
73
- "ESP32", // Hardware
74
- firmwareMD5, // MD5 hash
75
- numChunks, // Number of chunks
76
- false, // Not forced
77
- true, // BROADCAST MODE (Phase 2)
78
- true // Compressed (Phase 1)
79
- );
80
-
81
- // Monitor OTA progress
82
- otaTask->setCallback([]() {
83
- Serial.println("OTA announcement sent");
84
- });
85
- ```
86
-
87
- ### mesh.initOTAReceive()
88
-
89
- Initialize OTA receiver on a node to accept firmware updates.
90
-
91
- ```cpp
92
- void initOTAReceive(
93
- TSTRING role,
94
- std::function<void(size_t current, size_t total)> progressCallback = nullptr,
95
- bool acceptCompressed = true,
96
- bool acceptBroadcast = true
97
- )
98
- ```
99
-
100
- #### Parameters
101
-
102
- | Parameter | Type | Description | Default |
103
- |-----------|------|-------------|---------|
104
- | `role` | TSTRING | This node's role for matching firmware | Required |
105
- | `progressCallback` | function | Callback for progress updates (current, total) | nullptr |
106
- | `acceptCompressed` | bool | Accept compressed firmware (Phase 1) | true |
107
- | `acceptBroadcast` | bool | Accept broadcast OTA (Phase 2) | true |
108
-
109
- #### Example
110
-
111
- ```cpp
112
- mesh.initOTAReceive(
113
- "sensor",
114
- [](size_t current, size_t total) {
115
- Serial.printf("OTA Progress: %d/%d (%d%%)\n",
116
- current, total, (current * 100) / total);
117
- },
118
- true, // Accept compressed
119
- true // Accept broadcast
120
- );
121
- ```
122
-
123
- ---
124
-
125
- ## Broadcast OTA (Phase 2)
126
-
127
- ### Architecture
128
-
129
- Broadcast OTA distributes firmware to all nodes simultaneously instead of individually, dramatically reducing network traffic and update time.
130
-
131
- **Message Flow:**
132
-
133
- ```
134
- 1. Root Node Announces Update:
135
- Root → ALL: Broadcast Announce {role, hardware, md5, noPart, broadcasted=true}
136
-
137
- 2. Root Node Broadcasts Chunks:
138
- Root → ALL: Broadcast Data(chunk 0)
139
- Root → ALL: Broadcast Data(chunk 1)
140
- Root → ALL: Broadcast Data(chunk 2)
141
- ...
142
- Root → ALL: Broadcast Data(chunk N)
143
-
144
- 3. All Nodes Process:
145
- Each node:
146
- - Receives broadcasts
147
- - Assembles chunks
148
- - Verifies MD5
149
- - Flashes firmware
150
- - Reboots into new version
151
- ```
152
-
153
- ### Performance Comparison
154
-
155
- | Mesh Size | Unicast Transmissions | Broadcast Transmissions | Reduction | Time Improvement |
156
- |-----------|----------------------|------------------------|-----------|------------------|
157
- | 10 nodes | 1,500 | 150 | 90% | ~10x faster |
158
- | 50 nodes | 7,500 | 150 | 98% | ~50x faster |
159
- | 100 nodes | 15,000 | 150 | 99% | ~100x faster |
160
-
161
- *Assuming 150 firmware chunks*
162
-
163
- ### Memory Requirements
164
-
165
- **Per Node:**
166
- - Chunk buffer: ~1-2KB
167
- - Tracking bitmap: ~1KB (for 150 chunks)
168
- - Total overhead: +2-5KB
169
-
170
- **Scalability:**
171
- - Tested: Up to 100 nodes
172
- - Theoretical: 200+ nodes with proper rate limiting
173
- - Recommended: 10-100 nodes for optimal performance
174
-
175
- ### Implementation Details
176
-
177
- The broadcast mode is implemented through a minimal change to `src/painlessmesh/ota.hpp`:
178
-
179
- ```cpp
180
- static Data replyTo(const DataRequest& req, TSTRING data, size_t partNo) {
181
- Data d;
182
- // ... initialize fields ...
183
-
184
- // Phase 2: Set BROADCAST routing when broadcasted flag is true
185
- if (req.broadcasted) {
186
- d.routing = router::BROADCAST;
187
- }
188
- return d;
189
- }
190
- ```
191
-
192
- ### Best Practices
193
-
194
- 1. **Rate Limiting:** Don't broadcast chunks faster than nodes can process
195
- 2. **Chunk Size:** Use 1024-2048 byte chunks for optimal balance
196
- 3. **Network Stability:** Ensure mesh is stable before starting OTA
197
- 4. **Monitoring:** Use progress callbacks to track update status
198
- 5. **Fallback:** Keep unicast mode available for small deployments
199
-
200
- ---
201
-
202
- ## Firmware Status Reporting
203
-
204
- ### Alteriom MQTT Schema v1 Compliance
205
-
206
- The firmware update process can report status using the Alteriom MQTT schema `firmware_status.schema.json` v1.
207
-
208
- #### Schema Structure
209
-
210
- ```json
211
- {
212
- "schema_version": 1,
213
- "device_id": "node-123456",
214
- "device_type": "sensor",
215
- "timestamp": "2024-10-11T16:30:00Z",
216
- "firmware_version": "1.0.0",
217
- "status": "downloading",
218
- "from_version": "1.0.0",
219
- "to_version": "2.0.0",
220
- "progress_pct": 45.5,
221
- "error": null
222
- }
223
- ```
224
-
225
- #### Status Values
226
-
227
- | Status | Description | Required Fields |
228
- |--------|-------------|----------------|
229
- | `pending` | Update queued, not started | None |
230
- | `downloading` | Downloading firmware chunks | `progress_pct` recommended |
231
- | `flashing` | Writing firmware to flash | `progress_pct` recommended |
232
- | `verifying` | Verifying firmware integrity | None |
233
- | `rebooting` | Rebooting into new firmware | None |
234
- | `completed` | Update successful | `to_version` |
235
- | `failed` | Update failed | `error` required |
236
-
237
- #### Example Implementation
238
-
239
- ```cpp
240
- // Report OTA progress via MQTT
241
- void reportOTAStatus(String status, float progress = -1, String error = "") {
242
- DynamicJsonDocument doc(512);
243
-
244
- // Envelope fields (required)
245
- doc["schema_version"] = 1;
246
- doc["device_id"] = String(mesh.getNodeId());
247
- doc["device_type"] = "sensor";
248
- doc["timestamp"] = getCurrentISO8601Timestamp();
249
- doc["firmware_version"] = FIRMWARE_VERSION;
250
-
251
- // Firmware status fields
252
- doc["status"] = status;
253
- doc["from_version"] = OLD_VERSION;
254
- doc["to_version"] = NEW_VERSION;
255
-
256
- if (progress >= 0) {
257
- doc["progress_pct"] = progress;
258
- }
259
-
260
- if (error.length() > 0) {
261
- doc["error"] = error;
262
- } else {
263
- doc["error"] = nullptr;
264
- }
265
-
266
- String payload;
267
- serializeJson(doc, payload);
268
- mqttClient.publish("device/firmware/status", payload.c_str());
269
- }
270
-
271
- // Usage in OTA progress callback
272
- mesh.initOTAReceive("sensor", [](size_t current, size_t total) {
273
- float progress = (current * 100.0) / total;
274
-
275
- if (current == 0) {
276
- reportOTAStatus("downloading", 0);
277
- } else if (current < total) {
278
- reportOTAStatus("downloading", progress);
279
- } else {
280
- reportOTAStatus("flashing", 100);
281
- }
282
- });
283
- ```
284
-
285
- ---
286
-
287
- ## MQTT Schema Compliance
288
-
289
- ### Gateway Metrics
290
-
291
- The MQTT Status Bridge publishes gateway metrics in full compliance with Alteriom MQTT schema v1.
292
-
293
- **Schema:** `gateway_metrics.schema.json` v1
294
-
295
- **Required Fields:**
296
- - Envelope: `schema_version`, `device_id`, `device_type`, `timestamp`, `firmware_version`
297
- - Metrics: `uptime_s` (minimum required)
298
-
299
- **Published Message:**
300
- ```json
301
- {
302
- "schema_version": 1,
303
- "device_id": "gateway-001",
304
- "device_type": "gateway",
305
- "timestamp": "2024-10-11T16:30:00Z",
306
- "firmware_version": "2.1.0",
307
- "metrics": {
308
- "uptime_s": 3600,
309
- "mesh_nodes": 12,
310
- "memory_usage_pct": 45.2,
311
- "connected_devices": 12
312
- }
313
- }
314
- ```
315
-
316
- ### Validation
317
-
318
- To validate messages against the schema:
319
-
320
- ```javascript
321
- // Node.js validation example
322
- const { validators } = require('@alteriom/mqtt-schema');
323
-
324
- const message = JSON.parse(mqttPayload);
325
- const result = validators.gatewayMetrics(message);
326
-
327
- if (!result.valid) {
328
- console.error('Validation errors:', result.errors);
329
- }
330
- ```
331
-
332
- ---
333
-
334
- ## Complete Examples
335
-
336
- ### Example 1: Basic OTA Sender
337
-
338
- ```cpp
339
- #include <painlessMesh.h>
340
-
341
- #define MESH_PREFIX "mesh"
342
- #define MESH_PASSWORD "password"
343
- #define MESH_PORT 5555
344
-
345
- painlessMesh mesh;
346
-
347
- void setup() {
348
- Serial.begin(115200);
349
- mesh.init(MESH_PREFIX, MESH_PASSWORD, MESH_PORT);
350
-
351
- // Calculate firmware chunks
352
- File firmware = SD.open("/firmware.bin");
353
- size_t fileSize = firmware.size();
354
- size_t numChunks = (fileSize + 1023) / 1024; // 1KB chunks
355
- String md5 = calculateMD5(firmware);
356
-
357
- // Offer OTA with Phase 2 broadcast
358
- auto otaTask = mesh.offerOTA(
359
- "sensor",
360
- "ESP32",
361
- md5,
362
- numChunks,
363
- false, // not forced
364
- true, // BROADCAST
365
- true // compressed
366
- );
367
-
368
- Serial.println("Broadcasting OTA update...");
369
- }
370
-
371
- void loop() {
372
- mesh.update();
373
- }
374
- ```
375
-
376
- ### Example 2: OTA Receiver with Status Reporting
377
-
378
- ```cpp
379
- #include <painlessMesh.h>
380
- #include <PubSubClient.h>
381
-
382
- painlessMesh mesh;
383
- PubSubClient mqttClient;
384
-
385
- void reportOTAStatus(String status, float progress = -1) {
386
- // Implementation as shown above
387
- }
388
-
389
- void setup() {
390
- Serial.begin(115200);
391
- mesh.init(MESH_PREFIX, MESH_PASSWORD, MESH_PORT);
392
-
393
- // Initialize OTA receiver with progress reporting
394
- mesh.initOTAReceive(
395
- "sensor",
396
- [](size_t current, size_t total) {
397
- float pct = (current * 100.0) / total;
398
- Serial.printf("OTA: %d/%d (%.1f%%)\n", current, total, pct);
399
-
400
- // Report via MQTT
401
- if (current == 0) {
402
- reportOTAStatus("downloading", 0);
403
- } else if (current < total) {
404
- reportOTAStatus("downloading", pct);
405
- } else {
406
- reportOTAStatus("flashing", 100);
407
- }
408
- },
409
- true, // accept compressed
410
- true // accept broadcast
411
- );
412
- }
413
-
414
- void loop() {
415
- mesh.update();
416
- mqttClient.loop();
417
- }
418
- ```
419
-
420
- ### Example 3: Full MQTT Bridge with Schema Compliance
421
-
422
- ```cpp
423
- #include <painlessMesh.h>
424
- #include <PubSubClient.h>
425
- #include "examples/bridge/mqtt_status_bridge.hpp"
426
-
427
- painlessMesh mesh;
428
- WiFiClient wifiClient;
429
- PubSubClient mqttClient(wifiClient);
430
- MqttStatusBridge* statusBridge;
431
-
432
- void setup() {
433
- Serial.begin(115200);
434
-
435
- // Initialize mesh as bridge node
436
- mesh.init(MESH_PREFIX, MESH_PASSWORD, MESH_PORT, WIFI_AP_STA);
437
- mesh.setRoot(true);
438
- mesh.setContainsRoot(true);
439
- mesh.stationManual(WIFI_SSID, WIFI_PASSWORD);
440
-
441
- // Connect to MQTT broker
442
- mqttClient.setServer(MQTT_BROKER, 1883);
443
- mqttClient.connect("painlessMesh-bridge");
444
-
445
- // Initialize schema-compliant MQTT status bridge
446
- statusBridge = new MqttStatusBridge(mesh, mqttClient);
447
- statusBridge->setDeviceId("gateway-001");
448
- statusBridge->setFirmwareVersion("2.1.0");
449
- statusBridge->setPublishInterval(30000); // 30 seconds
450
- statusBridge->enableMetrics(true); // Schema v1 compliant
451
- statusBridge->enableTopology(true);
452
- statusBridge->enableAlerts(true);
453
- statusBridge->begin();
454
-
455
- Serial.println("MQTT Status Bridge started");
456
- Serial.println("Publishing schema-compliant gateway metrics");
457
- }
458
-
459
- void loop() {
460
- mesh.update();
461
- mqttClient.loop();
462
- }
463
- ```
464
-
465
- ---
466
-
467
- ## Troubleshooting
468
-
469
- ### Common Issues
470
-
471
- #### 1. OTA Not Starting
472
-
473
- **Symptom:** Nodes don't respond to OTA announcements
474
-
475
- **Solutions:**
476
- - Verify role matches between sender and receiver
477
- - Check hardware type (ESP32 vs ESP8266)
478
- - Ensure nodes have OTA initialized with `initOTAReceive()`
479
- - Check MD5 is different from current firmware
480
-
481
- #### 2. Broadcast OTA Slow/Failing
482
-
483
- **Symptom:** Broadcast mode slower than expected or nodes miss chunks
484
-
485
- **Solutions:**
486
- - Reduce broadcast rate (add delays between chunks)
487
- - Check mesh stability (`mesh.getNodeList()` should be stable)
488
- - Verify sufficient memory on nodes (check `ESP.getFreeHeap()`)
489
- - Consider smaller chunk size for congested meshes
490
- - Reduce number of nodes or use unicast for <10 nodes
491
-
492
- #### 3. Schema Validation Failures
493
-
494
- **Symptom:** MQTT consumers reject messages
495
-
496
- **Solutions:**
497
- - Verify `schema_version` is exactly 1 (integer)
498
- - Check `device_id` matches pattern `^[A-Za-z0-9_-]+$` (no spaces)
499
- - Ensure `device_type` is exactly "gateway" or "sensor"
500
- - Validate timestamp is ISO 8601: `YYYY-MM-DDTHH:MM:SSZ`
501
- - Check `firmware_version` is not empty and ≤40 characters
502
- - Ensure `metrics` object exists for gateway_metrics
503
- - Verify `uptime_s` is present and non-negative integer
504
-
505
- #### 4. Timestamp Issues
506
-
507
- **Symptom:** Timestamps rejected or incorrect
508
-
509
- **Solutions:**
510
- - Use NTP time sync for accurate timestamps
511
- - Implement RTC module for offline accuracy
512
- - Fallback implementation uses Unix epoch + millis()
513
- - Ensure format: `1970-01-15T12:34:56Z` (must include date and Z suffix)
514
- - Validate with regex: `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$`
515
-
516
- ### Debug Commands
517
-
518
- ```cpp
519
- // Enable OTA debug logging
520
- mesh.setDebugMsgTypes(ERROR | STARTUP | OTA);
521
-
522
- // Check OTA status
523
- Serial.printf("Accepting OTA: %s\n", mesh.isAcceptingOTA() ? "YES" : "NO");
524
-
525
- // Monitor memory during OTA
526
- Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap());
527
-
528
- // Validate MQTT message locally
529
- #include <ArduinoJson.h>
530
- DynamicJsonDocument doc(1024);
531
- deserializeJson(doc, mqttPayload);
532
- // Check required fields manually
533
- bool valid = doc.containsKey("schema_version") &&
534
- doc["schema_version"] == 1 &&
535
- doc.containsKey("metrics");
536
- ```
537
-
538
- ---
539
-
540
- ## References
541
-
542
- - **painlessMesh OTA Plugin:** [src/painlessmesh/ota.hpp](../src/painlessmesh/ota.hpp)
543
- - **MQTT Status Bridge:** [examples/bridge/mqtt_status_bridge.hpp](../examples/bridge/mqtt_status_bridge.hpp)
544
- - **Alteriom MQTT Schema:** https://www.npmjs.com/package/@alteriom/mqtt-schema
545
- - **Phase 2 Guide:** [PHASE2_GUIDE.md](PHASE2_GUIDE.md)
546
- - **Schema Compliance:** [MQTT_SCHEMA_COMPLIANCE.md](MQTT_SCHEMA_COMPLIANCE.md)
547
- - **Phase 2 Implementation:** [improvements/PHASE2_IMPLEMENTATION.md](improvements/PHASE2_IMPLEMENTATION.md)
548
-
549
- ---
550
-
551
- **Last Updated:** October 2024
552
- **Schema Version:** v1
553
- **painlessMesh Version:** 1.6.1+
554
- **Phase:** 2 (Broadcast OTA + MQTT Status Bridge)