@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
@@ -2,6 +2,34 @@
2
2
 
3
3
  This guide covers the most frequently encountered problems when working with painlessMesh and their solutions.
4
4
 
5
+ ## Architecture & Design Issues
6
+
7
+ ### Regular Nodes Cannot Access Internet / HTTP Requests Fail
8
+
9
+ **Symptoms:**
10
+ - HTTP/HTTPS requests fail with "connection refused"
11
+ - `WiFi.status()` shows disconnected on regular mesh nodes
12
+ - Internet services (APIs, WhatsApp bot, etc.) only work on bridge node
13
+
14
+ **Cause:**
15
+
16
+ This is **expected behavior**, not a bug. Only bridge nodes have internet access.
17
+
18
+ **Solution:**
19
+
20
+ See the dedicated guide for this common architecture mistake:
21
+
22
+ 📖 **[Common Architecture Mistakes](common-architecture-mistakes.md)**
23
+
24
+ **Quick Summary:**
25
+
26
+ painlessMesh uses a bridge-forwarding pattern:
27
+ - **Bridge node**: Has internet access, forwards data to/from internet
28
+ - **Regular nodes**: No internet access, send data to bridge
29
+ - **Architecture**: Regular nodes → Bridge → Internet
30
+
31
+ Regular nodes must send data to the bridge, which then forwards to internet services.
32
+
5
33
  ## Platform-Specific Issues
6
34
 
7
35
  ### ESP32-C6 Crashes on Startup
@@ -293,30 +293,131 @@ String createSecureMessage(String data) {
293
293
 
294
294
  ### Q: Can I connect the mesh to the internet?
295
295
 
296
- **A:** Yes, using bridge nodes:
296
+ **A:** Yes, using bridge nodes. **Important:** Only the bridge node has internet access - regular mesh nodes do NOT have internet access.
297
+
298
+ **Architecture:**
299
+ ```text
300
+ Internet
301
+ |
302
+ Router (WiFi)
303
+ |
304
+ Bridge Node (AP+STA mode) ← Only this node has internet access
305
+ |
306
+ Mesh Network
307
+ / | \
308
+ Node1 Node2 Node3... ← These nodes do NOT have internet access
309
+ ```
297
310
 
311
+ **Bridge Node Setup:**
298
312
  ```cpp
299
313
  // Bridge node connects to both mesh and internet
300
314
  void setup() {
301
- // Connect to mesh
315
+ // Modern approach: Auto-detect channel and connect
316
+ mesh.initAsBridge(MESH_PREFIX, MESH_PASSWORD,
317
+ ROUTER_SSID, ROUTER_PASSWORD,
318
+ &userScheduler, MESH_PORT);
319
+
320
+ mesh.onReceive(&receivedCallback);
321
+ }
322
+
323
+ // Forward mesh data to internet services
324
+ void receivedCallback(uint32_t from, String& msg) {
325
+ // Bridge forwards messages to HTTP server, MQTT broker, etc.
326
+ if (WiFi.status() == WL_CONNECTED) {
327
+ httpClient.POST("http://myserver.com/api/data", msg);
328
+ }
329
+ }
330
+ ```
331
+
332
+ **Regular Nodes:**
333
+ ```cpp
334
+ // Regular nodes send data TO the bridge (no direct internet access)
335
+ void setup() {
302
336
  mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
337
+ mesh.onReceive(&receivedCallback);
338
+ }
339
+
340
+ void sendDataToInternet() {
341
+ // Regular nodes send to bridge, which forwards to internet
342
+ String data = "{\"sensor\":\"temp\",\"value\":25.5}";
343
+ mesh.sendSingle(bridgeNodeId, data);
344
+ // Bridge will forward this to internet services
345
+ }
346
+ ```
347
+
348
+ See [BRIDGE_TO_INTERNET.md](../../BRIDGE_TO_INTERNET.md) for complete documentation.
349
+
350
+ ### Q: Why can't my regular mesh nodes access the Internet / make HTTP requests?
351
+
352
+ **A:** This is expected behavior. **Only the bridge node has internet access** - regular mesh nodes only communicate with other mesh nodes.
353
+
354
+ **Why this happens:**
355
+
356
+ ESP8266/ESP32 WiFi hardware can only operate on one channel at a time. In a mesh network:
357
+
358
+ - **Bridge node** uses `WIFI_AP_STA` mode:
359
+ - Access Point (AP) for mesh on channel X
360
+ - Station (STA) connected to router on channel X
361
+ - Has internet access via router
362
+
363
+ - **Regular nodes** use `WIFI_AP` mode:
364
+ - Access Point (AP) for mesh only
365
+ - No router connection
366
+ - No internet access
367
+
368
+ **Solution - Forward through bridge:**
369
+
370
+ ```cpp
371
+ // ==== BRIDGE NODE ====
372
+ #include "HTTPClient.h"
373
+
374
+ void receivedCallback(uint32_t from, String& msg) {
375
+ // Parse message from mesh nodes
376
+ DynamicJsonDocument doc(1024);
377
+ deserializeJson(doc, msg);
303
378
 
304
- // Also connect to home WiFi
305
- WiFi.begin("HomeWiFi", "password");
306
- while (WiFi.status() != WL_CONNECTED) {
307
- delay(500);
379
+ // Forward to internet service
380
+ if (WiFi.status() == WL_CONNECTED) {
381
+ HTTPClient http;
382
+ http.begin("http://api.example.com/data");
383
+ http.addHeader("Content-Type", "application/json");
384
+ http.POST(msg);
385
+ http.end();
308
386
  }
387
+ }
388
+
389
+ // ==== REGULAR NODE ====
390
+ void sendDataToCloud() {
391
+ // Create message
392
+ String msg = "{\"sensor\":\"temp\",\"value\":25.5}";
393
+
394
+ // Send to bridge (NOT directly to internet!)
395
+ mesh.sendSingle(bridgeNodeId, msg);
309
396
 
310
- Serial.println("Bridge node: Connected to both mesh and internet");
397
+ // Bridge will forward to internet service
311
398
  }
399
+ ```
312
400
 
313
- // Forward mesh data to internet services
314
- mesh.onReceive([](uint32_t from, String& msg) {
315
- // Forward to HTTP server, MQTT broker, etc.
316
- httpClient.POST("http://myserver.com/api/data", msg);
317
- });
401
+ **Common mistake:**
402
+
403
+ ```cpp
404
+ // ❌ This will NOT work on regular mesh nodes:
405
+ HTTPClient http;
406
+ http.begin("http://api.example.com/data");
407
+ http.POST(data); // ERROR: No internet connection!
408
+
409
+ // ✅ Correct approach - send to bridge:
410
+ mesh.sendSingle(bridgeNodeId, data); // Bridge forwards to internet
318
411
  ```
319
412
 
413
+ **Architecture patterns:**
414
+
415
+ 1. **Single bridge**: One node connects to router, others forward through it
416
+ 2. **Bridge failover**: Multiple nodes have router credentials, automatic failover
417
+ 3. **Multi-bridge**: Multiple simultaneous bridges for load balancing
418
+
419
+ See [BRIDGE_TO_INTERNET.md](../../BRIDGE_TO_INTERNET.md) and [BRIDGE_FAILOVER.md](../BRIDGE_FAILOVER.md).
420
+
320
421
  ### Q: Can I use MQTT with painlessMesh?
321
422
 
322
423
  **A:** Yes, through bridge nodes or by running MQTT alongside the mesh:
@@ -0,0 +1,40 @@
1
+ cmake_minimum_required(VERSION 3.10)
2
+ project(BasicExampleSimulatorTests)
3
+
4
+ set(CMAKE_CXX_STANDARD 14)
5
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+
7
+ # Path to the simulator (submodule)
8
+ set(SIMULATOR_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/simulator")
9
+
10
+ # Include simulator's CMake configuration
11
+ if(EXISTS "${SIMULATOR_ROOT}/CMakeLists.txt")
12
+ # Add simulator as subdirectory
13
+ add_subdirectory(${SIMULATOR_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/simulator)
14
+ else()
15
+ message(FATAL_ERROR "Simulator not found at ${SIMULATOR_ROOT}. Did you initialize the submodule?")
16
+ endif()
17
+
18
+ # Include painlessMesh library
19
+ set(PAINLESS_MESH_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../..")
20
+ include_directories(
21
+ ${PAINLESS_MESH_ROOT}/src
22
+ ${CMAKE_CURRENT_SOURCE_DIR}/firmware
23
+ )
24
+
25
+ # Register our custom firmware with the simulator
26
+ # This allows the YAML scenarios to reference "basic_example" template
27
+ add_library(basic_example_firmware INTERFACE)
28
+ target_include_directories(basic_example_firmware INTERFACE
29
+ ${CMAKE_CURRENT_SOURCE_DIR}/firmware
30
+ )
31
+
32
+ # Link with simulator
33
+ target_link_libraries(basic_example_firmware INTERFACE
34
+ painlessmesh_simulator
35
+ )
36
+
37
+ # The simulator executable will be built by the simulator's CMakeLists.txt
38
+ # We just need to ensure our firmware headers are available
39
+ message(STATUS "Basic example firmware tests configured")
40
+ message(STATUS "Run tests with: ./painlessmesh-simulator --config scenarios/basic_mesh_test.yaml")
@@ -0,0 +1,149 @@
1
+ # Basic Example - Simulator Tests
2
+
3
+ This directory contains simulator-based tests for the `basic.ino` example using the [painlessMesh-simulator](https://github.com/Alteriom/painlessMesh-simulator).
4
+
5
+ ## Overview
6
+
7
+ The simulator allows testing the basic example with 10+ virtual nodes without physical hardware, validating:
8
+ - Mesh formation with multiple nodes
9
+ - Message broadcasting to all nodes
10
+ - Callback functionality
11
+ - Dynamic node joining
12
+ - Time synchronization
13
+
14
+ ## Quick Start
15
+
16
+ ### Prerequisites
17
+
18
+ Install dependencies (Ubuntu/Debian):
19
+ ```bash
20
+ sudo apt-get install cmake ninja-build libboost-dev libboost-program-options-dev libyaml-cpp-dev
21
+ ```
22
+
23
+ ### Initialize Submodule
24
+
25
+ If not already done:
26
+ ```bash
27
+ cd ../../../../test
28
+ git submodule update --init simulator
29
+ cd -
30
+ ```
31
+
32
+ ### Build and Run
33
+
34
+ ```bash
35
+ # Build simulator
36
+ mkdir build && cd build
37
+ cmake -G Ninja ..
38
+ ninja
39
+
40
+ # Run test scenario
41
+ bin/painlessmesh-simulator --config ../scenarios/basic_mesh_test.yaml
42
+
43
+ # Or using the simulator from test/simulator
44
+ cd ../../../../test/simulator
45
+ mkdir -p build && cd build
46
+ cmake -G Ninja ..
47
+ ninja
48
+ bin/painlessmesh-simulator --config ../../../examples/basic/test/simulator/scenarios/basic_mesh_test.yaml
49
+ ```
50
+
51
+ ## Test Scenarios
52
+
53
+ ### basic_mesh_test.yaml
54
+
55
+ Tests basic functionality with 10 nodes:
56
+ - ✓ Mesh formation
57
+ - ✓ Message broadcasting
58
+ - ✓ Callback triggering
59
+ - ✓ Dynamic node joining (node added at 30s)
60
+ - ✓ Time synchronization
61
+
62
+ **Expected Results:**
63
+ - All nodes connect within 30 seconds
64
+ - Each node receives 5+ messages within 60 seconds
65
+ - Time differences < 10ms after 45 seconds
66
+
67
+ ## Firmware Adapter
68
+
69
+ The `firmware/basic_firmware.hpp` file wraps the `basic.ino` logic for simulation:
70
+
71
+ ```cpp
72
+ #include "simulator/firmware/firmware_base.hpp"
73
+
74
+ class BasicFirmware : public FirmwareBase {
75
+ // Implements same logic as basic.ino
76
+ // - setup() initializes mesh and callbacks
77
+ // - loop() calls mesh.update()
78
+ // - sendMessage() broadcasts periodically
79
+ };
80
+ ```
81
+
82
+ This allows running the **exact same code** that runs on hardware.
83
+
84
+ ## Adding More Tests
85
+
86
+ Create new YAML scenarios in `scenarios/`:
87
+
88
+ ```yaml
89
+ simulation:
90
+ name: "Stress Test"
91
+ duration: 120
92
+
93
+ nodes:
94
+ - template: "basic_example"
95
+ count: 50 # Test with 50 nodes
96
+
97
+ topology:
98
+ type: "ring" # Different topology
99
+
100
+ events:
101
+ - type: "network_partition" # Inject failures
102
+ time: 60
103
+ ```
104
+
105
+ ## Metrics and Validation
106
+
107
+ Test results are saved to `results/basic_test_results.csv`:
108
+
109
+ ```csv
110
+ timestamp,node_id,messages_sent,messages_received,topology_changes
111
+ 0,6481,0,0,1
112
+ 1,6481,1,0,1
113
+ 2,6481,1,2,1
114
+ ...
115
+ ```
116
+
117
+ Analyze with:
118
+ ```python
119
+ import pandas as pd
120
+ df = pd.read_csv('results/basic_test_results.csv')
121
+ print(df.groupby('node_id')['messages_received'].sum())
122
+ ```
123
+
124
+ ## Documentation
125
+
126
+ - [Simulator Documentation](../../../../test/simulator/README.md)
127
+ - [Integration Guide](../../../../test/simulator/docs/INTEGRATING_INTO_YOUR_PROJECT.md)
128
+ - [Configuration Reference](../../../../test/simulator/docs/CONFIGURATION_GUIDE.md)
129
+
130
+ ## Troubleshooting
131
+
132
+ **Simulator not found:**
133
+ ```bash
134
+ cd ../../../../test
135
+ git submodule update --init simulator
136
+ ```
137
+
138
+ **Build errors:**
139
+ ```bash
140
+ # Check dependencies
141
+ sudo apt-get install libboost-dev libyaml-cpp-dev
142
+
143
+ # Clean build
144
+ rm -rf build && mkdir build && cd build
145
+ cmake -G Ninja ..
146
+ ```
147
+
148
+ **Test failures:**
149
+ Check the simulator output for details on which validation failed.
@@ -0,0 +1,117 @@
1
+ #pragma once
2
+
3
+ #include "simulator/firmware/firmware_base.hpp"
4
+ #include <painlessMesh.h>
5
+
6
+ /**
7
+ * @brief Firmware adapter for basic.ino example
8
+ *
9
+ * This wraps the basic example sketch logic for testing with the simulator.
10
+ * It allows running the exact same code that runs on ESP32/ESP8266 hardware
11
+ * in a simulated environment with 100+ virtual nodes.
12
+ */
13
+ class BasicFirmware : public FirmwareBase {
14
+ public:
15
+ BasicFirmware() : mesh_(nullptr), userScheduler_(nullptr) {}
16
+
17
+ ~BasicFirmware() override {
18
+ if (taskSendMessage_) {
19
+ delete taskSendMessage_;
20
+ }
21
+ }
22
+
23
+ void setup(painlessMesh* mesh, Scheduler* userScheduler) override {
24
+ mesh_ = mesh;
25
+ userScheduler_ = userScheduler;
26
+
27
+ // Same configuration as basic.ino
28
+ const char* MESH_PREFIX = "whateverYouLike";
29
+ const char* MESH_PASSWORD = "somethingSneaky";
30
+ const uint16_t MESH_PORT = 5555;
31
+
32
+ // Set debug message types (same as basic.ino)
33
+ mesh_->setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
34
+
35
+ // Initialize mesh
36
+ mesh_->init(MESH_PREFIX, MESH_PASSWORD, userScheduler_, MESH_PORT);
37
+
38
+ // Register callbacks
39
+ mesh_->onReceive([this](uint32_t from, String& msg) {
40
+ this->receivedCallback(from, msg);
41
+ });
42
+
43
+ mesh_->onNewConnection([this](uint32_t nodeId) {
44
+ this->newConnectionCallback(nodeId);
45
+ });
46
+
47
+ mesh_->onChangedConnections([this]() {
48
+ this->changedConnectionCallback();
49
+ });
50
+
51
+ mesh_->onNodeTimeAdjusted([this](int32_t offset) {
52
+ this->nodeTimeAdjustedCallback(offset);
53
+ });
54
+
55
+ // Setup periodic message sending task
56
+ taskSendMessage_ = new Task(TASK_SECOND * 1, TASK_FOREVER,
57
+ [this]() { this->sendMessage(); });
58
+ userScheduler_->addTask(*taskSendMessage_);
59
+ taskSendMessage_->enable();
60
+ }
61
+
62
+ void loop() override {
63
+ if (mesh_) {
64
+ mesh_->update();
65
+ }
66
+ }
67
+
68
+ const char* getName() const override {
69
+ return "BasicExample";
70
+ }
71
+
72
+ private:
73
+ painlessMesh* mesh_;
74
+ Scheduler* userScheduler_;
75
+ Task* taskSendMessage_ = nullptr;
76
+
77
+ void sendMessage() {
78
+ if (!mesh_) return;
79
+
80
+ String msg = "Hello from node ";
81
+ msg += mesh_->getNodeId();
82
+ mesh_->sendBroadcast(msg);
83
+
84
+ // Random interval between 1 and 5 seconds (same as basic.ino)
85
+ taskSendMessage_->setInterval(random(TASK_SECOND * 1, TASK_SECOND * 5));
86
+ }
87
+
88
+ void receivedCallback(uint32_t from, String& msg) {
89
+ // In simulator, we can log to stdout or collect metrics
90
+ printf("Node %u: Received from %u msg=%s\n",
91
+ mesh_->getNodeId(), from, msg.c_str());
92
+
93
+ // Track metrics for validation
94
+ messagesReceived_++;
95
+ }
96
+
97
+ void newConnectionCallback(uint32_t nodeId) {
98
+ printf("Node %u: New Connection, nodeId = %u\n",
99
+ mesh_->getNodeId(), nodeId);
100
+ connectionsEstablished_++;
101
+ }
102
+
103
+ void changedConnectionCallback() {
104
+ printf("Node %u: Changed connections\n", mesh_->getNodeId());
105
+ topologyChanges_++;
106
+ }
107
+
108
+ void nodeTimeAdjustedCallback(int32_t offset) {
109
+ printf("Node %u: Adjusted time %u. Offset = %d\n",
110
+ mesh_->getNodeId(), mesh_->getNodeTime(), offset);
111
+ }
112
+
113
+ // Metrics for test validation
114
+ uint32_t messagesReceived_ = 0;
115
+ uint32_t connectionsEstablished_ = 0;
116
+ uint32_t topologyChanges_ = 0;
117
+ };
@@ -0,0 +1,81 @@
1
+ # Test scenario for basic.ino example
2
+ # This validates that the basic example works correctly with multiple nodes
3
+
4
+ simulation:
5
+ name: "Basic Example - Mesh Formation and Broadcasting"
6
+ description: "Validates basic.ino with 10 nodes forming a mesh and exchanging messages"
7
+ duration: 60 # seconds
8
+ time_scale: 1.0
9
+ seed: 12345
10
+
11
+ network:
12
+ default_latency:
13
+ min_ms: 1
14
+ max_ms: 10
15
+ default_packet_loss:
16
+ rate: 0.0
17
+ default_bandwidth:
18
+ bits_per_second: 1000000
19
+
20
+ nodes:
21
+ # Create individual nodes - simulator doesn't support template/count syntax
22
+ - id: "node1"
23
+ firmware: "SimpleBroadcast"
24
+ config:
25
+ mesh_prefix: "whateverYouLike"
26
+ mesh_password: "somethingSneaky"
27
+ mesh_port: 5555
28
+ broadcast_interval: "1000"
29
+ broadcast_message: "Hello from node"
30
+
31
+ - id: "node2"
32
+ firmware: "SimpleBroadcast"
33
+ config:
34
+ mesh_prefix: "whateverYouLike"
35
+ mesh_password: "somethingSneaky"
36
+ mesh_port: 5555
37
+ broadcast_interval: "1000"
38
+ broadcast_message: "Hello from node"
39
+
40
+ - id: "node3"
41
+ firmware: "SimpleBroadcast"
42
+ config:
43
+ mesh_prefix: "whateverYouLike"
44
+ mesh_password: "somethingSneaky"
45
+ mesh_port: 5555
46
+ broadcast_interval: "1000"
47
+ broadcast_message: "Hello from node"
48
+
49
+ - id: "node4"
50
+ firmware: "SimpleBroadcast"
51
+ config:
52
+ mesh_prefix: "whateverYouLike"
53
+ mesh_password: "somethingSneaky"
54
+ mesh_port: 5555
55
+ broadcast_interval: "1000"
56
+ broadcast_message: "Hello from node"
57
+
58
+ - id: "node5"
59
+ firmware: "SimpleBroadcast"
60
+ config:
61
+ mesh_prefix: "whateverYouLike"
62
+ mesh_password: "somethingSneaky"
63
+ mesh_port: 5555
64
+ broadcast_interval: "1000"
65
+ broadcast_message: "Hello from node"
66
+
67
+ topology:
68
+ type: "mesh" # Full mesh - all nodes connected
69
+
70
+ # No events - nodes start automatically
71
+ events: []
72
+
73
+ # Metrics to collect
74
+ metrics:
75
+ output: "basic_test_results.csv"
76
+ interval: 5
77
+ collect:
78
+ - "messages_sent"
79
+ - "messages_received"
80
+ - "bytes_sent"
81
+ - "bytes_received"
@@ -47,9 +47,22 @@ void setup() {
47
47
  // 3. Set this node as root
48
48
  // 4. Maintain router connection
49
49
  // 5. Start broadcasting bridge status (Type 610) every 30 seconds
50
- mesh.initAsBridge(MESH_PREFIX, MESH_PASSWORD,
51
- ROUTER_SSID, ROUTER_PASSWORD,
52
- &userScheduler, MESH_PORT);
50
+ bool bridgeSuccess = mesh.initAsBridge(MESH_PREFIX, MESH_PASSWORD,
51
+ ROUTER_SSID, ROUTER_PASSWORD,
52
+ &userScheduler, MESH_PORT);
53
+
54
+ if (!bridgeSuccess) {
55
+ Serial.println("✗ Failed to initialize as bridge!");
56
+ Serial.println("Router unreachable - falling back to regular mesh node");
57
+ Serial.println("The node will join the mesh without bridge functionality");
58
+
59
+ // Fallback: Initialize as regular mesh node
60
+ // This allows the device to still participate in the mesh
61
+ mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
62
+
63
+ Serial.println("✓ Initialized as regular mesh node");
64
+ Serial.println("Note: To function as a bridge, fix router connectivity and restart");
65
+ }
53
66
 
54
67
  // Optional: Configure bridge status broadcasting
55
68
  // mesh.setBridgeStatusInterval(60000); // Change to 60 seconds
@@ -61,7 +74,7 @@ void setup() {
61
74
  // Set up message callback
62
75
  mesh.onReceive(&receivedCallback);
63
76
 
64
- Serial.println("Bridge node initialized and ready!");
77
+ Serial.println("✓ Bridge node initialized and ready!");
65
78
  Serial.println("Broadcasting bridge status to mesh every 30 seconds");
66
79
  }
67
80