@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
@@ -105,6 +105,29 @@ To prevent oscillation:
105
105
  #define INITIAL_BRIDGE false
106
106
  ```
107
107
 
108
+ ### Channel Detection (Automatic)
109
+
110
+ **Critical for Bridge Discovery:**
111
+
112
+ Regular nodes **must** use channel auto-detection (channel=0) to discover bridges. This is because:
113
+
114
+ 1. Bridge nodes operate on the **router's WiFi channel** (e.g., channel 6)
115
+ 2. Regular nodes scanning on a fixed channel (e.g., channel 1) cannot see bridges on different channels
116
+ 3. Channel auto-detection scans all channels to find the mesh
117
+
118
+ The example code automatically uses channel=0:
119
+ ```cpp
120
+ // Regular node initialization with auto-detection
121
+ mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 0);
122
+ // ^ channel=0
123
+ ```
124
+
125
+ **What happens:**
126
+ - Node scans all WiFi channels (1-13) to find the mesh SSID
127
+ - Detects the channel where the bridge/mesh is operating
128
+ - Joins the mesh on that channel
129
+ - Ensures proper bridge discovery and mesh connectivity
130
+
108
131
  ## Setup Instructions
109
132
 
110
133
  You can choose between two deployment modes:
@@ -237,6 +260,14 @@ mesh.setElectionTimeout(5000);
237
260
  // Prevents nodes with poor signal from becoming bridges when isolated
238
261
  mesh.setMinimumBridgeRSSI(-80);
239
262
 
263
+ // Set startup delay before first election check (default: 60000 ms = 60 seconds)
264
+ // Longer delays allow more time for mesh formation, reducing split-brain risk
265
+ mesh.setElectionStartupDelay(90000); // 90 seconds
266
+
267
+ // Set random delay range for elections (default: 1000-3000 ms)
268
+ // Longer delays reduce simultaneous election risk when multiple nodes start together
269
+ mesh.setElectionRandomDelay(10000, 30000); // 10-30 seconds
270
+
240
271
  // Set bridge status broadcast interval
241
272
  mesh.setBridgeStatusInterval(30000);
242
273
 
@@ -337,12 +368,62 @@ bool amBridge = mesh.isBridge();
337
368
 
338
369
  **Symptoms**: Regular nodes show "No primary bridge available!" and "Known bridges: 0"
339
370
 
371
+ **Root Cause**: Regular nodes must use channel auto-detection (channel=0) to discover bridges on the router's channel.
372
+
340
373
  **Solutions**:
374
+ - **CRITICAL**: Initialize regular nodes with `channel=0` for auto-detection:
375
+ ```cpp
376
+ mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 0);
377
+ ```
341
378
  - Verify bridge node successfully connected to router (check serial output)
342
379
  - Ensure mesh network name and password match on all nodes
343
380
  - Check that nodes are on the same WiFi channel as the router/bridge
344
381
  - Wait a few seconds after startup for initial discovery
345
382
  - Bridge now broadcasts immediately on startup and when nodes connect (fixed in v1.8.4+)
383
+ - **Note**: The example code has been updated to use channel=0 by default
384
+
385
+ ### Split-Brain Scenario (Multiple Bridges)
386
+
387
+ **Symptoms**: When nodes start simultaneously, both become bridges and don't see each other
388
+
389
+ **Root Cause**: Race condition - both nodes detect "no bridge" after startup period, run isolated elections, each wins their own election and becomes a bridge.
390
+
391
+ **Why This Happens**:
392
+ 1. Both nodes initialize as regular nodes with `INITIAL_BRIDGE = false`
393
+ 2. After 60s startup period, both detect "no bridge exists"
394
+ 3. Both trigger elections with short 1-3s random delay
395
+ 4. If mesh connection hasn't formed yet, each runs an isolated election
396
+ 5. Each node wins its own election and becomes a bridge
397
+ 6. Once both are bridges, they stop scanning for mesh nodes
398
+
399
+ **Solutions**:
400
+
401
+ **Option 1: Increase Startup Delay (Recommended)**
402
+ ```cpp
403
+ // Allow more time for mesh formation before elections start
404
+ mesh.setElectionStartupDelay(90000); // 90 seconds instead of default 60 seconds
405
+ ```
406
+
407
+ **Option 2: Increase Random Election Delay**
408
+ ```cpp
409
+ // Provide more mesh discovery time when elections trigger
410
+ mesh.setElectionRandomDelay(10000, 30000); // 10-30 seconds instead of 1-3 seconds
411
+ ```
412
+
413
+ **Option 3: Combine Both**
414
+ ```cpp
415
+ mesh.setElectionStartupDelay(90000); // 90 second startup delay
416
+ mesh.setElectionRandomDelay(10000, 30000); // 10-30 second random delay
417
+ ```
418
+
419
+ **Option 4: Stagger Node Startup**
420
+ - Power on nodes 10-20 seconds apart
421
+ - First node establishes mesh, second node discovers it
422
+
423
+ **Option 5: Use Pre-Designated Bridge**
424
+ - Set `INITIAL_BRIDGE = true` on one node only
425
+ - Guarantees single bridge from startup
426
+ - Good for fixed deployments
346
427
 
347
428
  ### Bridge Reports No Internet When Router Has Internet
348
429
 
@@ -34,6 +34,12 @@
34
34
  // - Deterministic winner selection with tiebreakers
35
35
  // - Seamless promotion to bridge role
36
36
  // - Bridge takeover announcements
37
+ // - Automatic mesh channel detection for bridge discovery
38
+ //
39
+ // Important Note:
40
+ // Regular nodes MUST use channel auto-detection (channel=0) to discover
41
+ // bridges that are operating on the router's WiFi channel. The example
42
+ // automatically uses channel=0 for this purpose.
37
43
  //
38
44
  //************************************************************
39
45
 
@@ -132,7 +138,8 @@ void setup() {
132
138
 
133
139
  // Fallback: Initialize as regular node with bridge failover enabled
134
140
  // This allows automatic promotion to bridge when router becomes available
135
- mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
141
+ // channel=0 enables automatic mesh channel detection
142
+ mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 0);
136
143
  mesh.setRouterCredentials(ROUTER_SSID, ROUTER_PASSWORD);
137
144
  mesh.enableBridgeFailover(true);
138
145
  mesh.setElectionTimeout(5000);
@@ -143,8 +150,9 @@ void setup() {
143
150
  Serial.println("Mode: REGULAR NODE (Failover Enabled)");
144
151
  Serial.println("This node can become bridge via election\n");
145
152
 
146
- // Initialize as regular node
147
- mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
153
+ // Initialize as regular node with auto-channel detection
154
+ // channel=0 enables automatic mesh channel detection
155
+ mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 0);
148
156
 
149
157
  // Configure for automatic bridge failover
150
158
  mesh.setRouterCredentials(ROUTER_SSID, ROUTER_PASSWORD);
@@ -154,6 +162,14 @@ void setup() {
154
162
  // Optional: Set minimum RSSI for isolated bridge elections (default: -80 dBm)
155
163
  // This prevents nodes with poor signal from becoming bridges when isolated
156
164
  // mesh.setMinimumBridgeRSSI(-80); // Uncomment to customize threshold
165
+
166
+ // Optional: Configure election timing to prevent split-brain when nodes start simultaneously
167
+ // Longer startup delay allows more time for mesh formation before elections begin
168
+ // mesh.setElectionStartupDelay(90000); // 90 seconds (default: 60 seconds)
169
+
170
+ // Optional: Increase random delay to reduce simultaneous election risk
171
+ // Longer delays provide more mesh discovery time when multiple nodes detect missing bridge
172
+ // mesh.setElectionRandomDelay(10000, 30000); // 10-30 seconds (default: 1-3 seconds)
157
173
  }
158
174
 
159
175
  // Register callbacks
@@ -186,6 +202,7 @@ void loop() {
186
202
  Serial.println("\n--- Bridge Status ---");
187
203
  Serial.printf("I am bridge: %s\n", mesh.isBridge() ? "YES" : "NO");
188
204
  Serial.printf("Internet available: %s\n", mesh.hasInternetConnection() ? "YES" : "NO");
205
+ Serial.printf("Mesh connections active: %s\n", mesh.hasActiveMeshConnections() ? "YES" : "NO");
189
206
 
190
207
  auto bridges = mesh.getBridges();
191
208
  Serial.printf("Known bridges: %d\n", bridges.size());
@@ -203,7 +220,21 @@ void loop() {
203
220
  Serial.printf("Primary bridge: %u (RSSI: %d dBm)\n",
204
221
  primary->nodeId, primary->routerRSSI);
205
222
  } else {
206
- Serial.println("No primary bridge available!");
223
+ // Provide more context about why no primary bridge
224
+ if (!mesh.hasActiveMeshConnections()) {
225
+ Serial.println("No primary bridge: This node is disconnected from mesh");
226
+ // Show last known bridge info if available
227
+ auto lastKnown = mesh.getLastKnownBridge();
228
+ if (lastKnown) {
229
+ Serial.printf(" Last known bridge: %u (RSSI: %d dBm, last seen %u ms ago)\n",
230
+ lastKnown->nodeId, lastKnown->routerRSSI,
231
+ millis() - lastKnown->lastSeen);
232
+ }
233
+ } else if (bridges.empty()) {
234
+ Serial.println("No primary bridge: No bridges discovered yet");
235
+ } else {
236
+ Serial.println("No primary bridge: Known bridges timed out or lost Internet");
237
+ }
207
238
  }
208
239
  Serial.println("--------------------\n");
209
240
  }
@@ -0,0 +1,235 @@
1
+ # Shared Gateway Example
2
+
3
+ This example demonstrates the **Shared Gateway Mode** feature of painlessMesh. Unlike Bridge Mode where only one node connects to the router, Shared Gateway Mode allows **ALL nodes** to connect to the same WiFi router while maintaining mesh connectivity.
4
+
5
+ ## What is Shared Gateway Mode?
6
+
7
+ In a traditional painlessMesh network:
8
+ - Regular nodes only communicate over the mesh
9
+ - Bridge nodes connect to a router AND the mesh
10
+ - Only the bridge can access the Internet
11
+
12
+ With Shared Gateway Mode:
13
+ - **All nodes** connect to the same WiFi router
14
+ - **All nodes** maintain mesh connectivity
15
+ - **Any node** can access the Internet directly
16
+ - Provides redundant Internet paths
17
+
18
+ ## Architecture
19
+
20
+ ```
21
+ Internet
22
+ │
23
+ Router
24
+ ┌─────────────┼─────────────┐
25
+ │ │ │
26
+ Node A Node B Node C
27
+ (AP+STA) (AP+STA) (AP+STA)
28
+ │ │ │
29
+ └─────────────┼─────────────┘
30
+ Mesh Network
31
+ ```
32
+
33
+ ## Hardware Requirements
34
+
35
+ - **ESP32** or **ESP8266** microcontroller
36
+ - WiFi router within range of all nodes
37
+ - USB cable for programming and serial monitoring
38
+
39
+ ## Configuration
40
+
41
+ Edit the following defines in `sharedGateway.ino`:
42
+
43
+ ```cpp
44
+ // Mesh network settings (must match across all nodes)
45
+ #define MESH_PREFIX "SharedGatewayMesh" // Your mesh network name
46
+ #define MESH_PASSWORD "meshPassword123" // Your mesh network password
47
+ #define MESH_PORT 5555 // TCP port (default: 5555)
48
+
49
+ // Router settings (your WiFi router)
50
+ #define ROUTER_SSID "YourRouterSSID" // Your WiFi router name
51
+ #define ROUTER_PASSWORD "YourRouterPassword" // Your WiFi router password
52
+ ```
53
+
54
+ ## Building and Uploading
55
+
56
+ ### Using PlatformIO (Recommended)
57
+
58
+ ```bash
59
+ # For ESP32
60
+ pio run -e esp32 -t upload
61
+
62
+ # For ESP8266
63
+ pio run -e esp8266 -t upload
64
+ ```
65
+
66
+ ### Using Arduino IDE
67
+
68
+ 1. Open `sharedGateway.ino` in Arduino IDE
69
+ 2. Install the required libraries:
70
+ - ArduinoJson
71
+ - TaskScheduler
72
+ - painlessMesh
73
+ - AsyncTCP (ESP32) or ESPAsyncTCP (ESP8266)
74
+ 3. Select your board (ESP32 or ESP8266)
75
+ 4. Click Upload
76
+
77
+ ## Expected Serial Output
78
+
79
+ After uploading, open Serial Monitor at 115200 baud. You should see:
80
+
81
+ ```
82
+ ================================================
83
+ painlessMesh - Shared Gateway Example
84
+ ================================================
85
+
86
+ Initializing Shared Gateway Mode...
87
+
88
+ Mesh SSID: SharedGatewayMesh
89
+ Mesh Port: 5555
90
+ Router SSID: YourRouterSSID
91
+
92
+ === Shared Gateway Mode Initialization ===
93
+ Step 1: Scanning for router YourRouterSSID to detect channel...
94
+ ✓ Router connected on channel 6
95
+ ✓ Router IP: 192.168.1.105
96
+ Step 2: Initializing mesh on channel 6...
97
+ Step 3: Establishing router connection in shared gateway mode...
98
+ === Shared Gateway Mode Active ===
99
+ Mesh Prefix: SharedGatewayMesh
100
+ Mesh Channel: 6 (synced with router)
101
+ Router: YourRouterSSID
102
+ Port: 5555
103
+ Mode: AP+STA (all nodes can connect to router)
104
+
105
+ ✓ Shared Gateway Mode initialized successfully!
106
+
107
+ ================================================
108
+ Node ID: 2748965421
109
+ Shared Gateway Mode: Active
110
+ Router IP: 192.168.1.105
111
+ Router Channel: 6
112
+ ================================================
113
+
114
+ Status broadcasts will be sent every 10 seconds.
115
+ ```
116
+
117
+ ### Status Broadcast Output
118
+
119
+ Every 10 seconds, you'll see:
120
+
121
+ ```
122
+ ========== STATUS BROADCAST ==========
123
+ Node ID: 2748965421
124
+ Router: Connected
125
+ IP: 192.168.1.105
126
+ RSSI: -45 dBm
127
+ Channel: 6
128
+ Mesh Nodes: 2
129
+ Shared Gateway Mode: Yes
130
+ Free Heap: 45320 bytes
131
+ Uptime: 120 seconds
132
+ =======================================
133
+ ```
134
+
135
+ ## Use Cases
136
+
137
+ ### Industrial Sensor Networks
138
+ All sensor nodes can independently send data to cloud services, providing redundancy if any individual node loses connection.
139
+
140
+ ### Fish Farm Monitoring
141
+ Critical O2 alarms can reach the cloud through any available path, ensuring no alerts are missed.
142
+
143
+ ### Smart Building Systems
144
+ HVAC and security data maintains connectivity through redundant paths for maximum reliability.
145
+
146
+ ### Remote Monitoring
147
+ Environmental monitoring stations with shared WiFi infrastructure can relay through nearby nodes if needed.
148
+
149
+ ## Troubleshooting
150
+
151
+ ### Router Connection Fails
152
+
153
+ **Symptoms:** `✗ Failed to initialize Shared Gateway Mode!`
154
+
155
+ **Solutions:**
156
+ 1. Verify router SSID and password are correct
157
+ 2. Ensure the router is powered on and within range
158
+ 3. Check that the router is operating on 2.4GHz (5GHz not supported)
159
+ 4. Try moving the node closer to the router
160
+
161
+ ### Mesh Not Forming
162
+
163
+ **Symptoms:** `Mesh Nodes: 0` even with multiple nodes
164
+
165
+ **Solutions:**
166
+ 1. Ensure all nodes use the same `MESH_PREFIX` and `MESH_PASSWORD`
167
+ 2. Verify all nodes are using the same router (same channel)
168
+ 3. Check that nodes are within WiFi range of each other
169
+ 4. Restart all nodes simultaneously
170
+
171
+ ### Frequent Router Disconnections
172
+
173
+ **Symptoms:** Router status alternates between Connected/Disconnected
174
+
175
+ **Solutions:**
176
+ 1. Check router signal strength (RSSI should be > -70 dBm)
177
+ 2. Move nodes closer to the router
178
+ 3. Reduce number of devices on the router
179
+ 4. Check for WiFi interference
180
+
181
+ ### Low Memory Warnings
182
+
183
+ **Symptoms:** `Free Heap` decreasing or node crashes
184
+
185
+ **Solutions:**
186
+ 1. Reduce JSON document sizes in your code
187
+ 2. Limit the number of mesh nodes
188
+ 3. Use ESP32 instead of ESP8266 for larger networks
189
+
190
+ ## API Reference
191
+
192
+ ### Key Method
193
+
194
+ ```cpp
195
+ bool initAsSharedGateway(
196
+ String meshPrefix, // Mesh network name
197
+ String meshPassword, // Mesh network password
198
+ String routerSSID, // Router SSID to connect to
199
+ String routerPassword, // Router password
200
+ Scheduler* scheduler, // Task scheduler
201
+ uint16_t port = 5555 // TCP port (optional)
202
+ );
203
+ ```
204
+
205
+ **Returns:** `true` if initialization succeeded, `false` if router connection failed.
206
+
207
+ ### Status Methods
208
+
209
+ ```cpp
210
+ // Check if shared gateway mode is active
211
+ bool isSharedGatewayMode();
212
+
213
+ // Get router connection status
214
+ WiFi.status() == WL_CONNECTED
215
+
216
+ // Get router IP address
217
+ WiFi.localIP()
218
+
219
+ // Get router signal strength
220
+ WiFi.RSSI()
221
+
222
+ // Get current WiFi channel
223
+ WiFi.channel()
224
+ ```
225
+
226
+ ## Related Documentation
227
+
228
+ - [Shared Gateway Design Document](../../docs/design/SHARED_GATEWAY_DESIGN.md)
229
+ - [Bridge Mode Example](../bridge/README.md)
230
+ - [Bridge Failover Example](../bridge_failover/README.md)
231
+ - [painlessMesh Documentation](https://gitlab.com/painlessMesh/painlessMesh/-/wikis/home)
232
+
233
+ ## License
234
+
235
+ This example is part of painlessMesh and is released under the same license.
@@ -7,6 +7,7 @@ lib_deps =
7
7
  arkhipenko/TaskScheduler
8
8
 
9
9
  lib_ldf_mode = deep+
10
+
10
11
  [env:esp8266]
11
12
  platform = espressif8266
12
13
  board = nodemcuv2
@@ -14,7 +15,7 @@ framework = arduino
14
15
  lib_extra_dirs = ../../
15
16
  lib_deps =
16
17
  ${env.lib_deps}
17
- me-no-dev/ESPAsyncTCP
18
+ esp32async/ESPAsyncTCP@^2.0.0
18
19
 
19
20
  [env:esp32]
20
21
  platform = espressif32
@@ -23,4 +24,4 @@ framework = arduino
23
24
  lib_extra_dirs = ../../
24
25
  lib_deps =
25
26
  ${env.lib_deps}
26
- mathieucarbou/AsyncTCP
27
+ esp32async/AsyncTCP