@alteriom/painlessmesh 1.9.19 → 1.10.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 (51) hide show
  1. package/CHANGELOG.md +168 -0
  2. package/README.md +102 -63
  3. package/RELEASE_GUIDE.md +147 -8
  4. package/examples/alteriom/README.md +4 -4
  5. package/examples/alteriom/alteriom_custom_package_template.hpp +320 -0
  6. package/examples/alteriom/alteriom_sensor_package.hpp +1 -1
  7. package/examples/alteriom/mppt_example/alteriom_mppt_example.ino +208 -0
  8. package/examples/bridge_failover/bridge_failover.ino +17 -0
  9. package/examples/sendToInternet/CMakeLists.txt +54 -0
  10. package/examples/sendToInternet/PC_NODE_README.md +517 -0
  11. package/examples/sendToInternet/README.md +39 -1
  12. package/examples/sendToInternet/build.sh +153 -0
  13. package/examples/sendToInternet/mock_server_test.ino +361 -0
  14. package/examples/sendToInternet/pc_mesh_node.cpp +361 -0
  15. package/examples/tcpRetryConfig/README.md +110 -0
  16. package/examples/tcpRetryConfig/platformio.ini +26 -0
  17. package/examples/tcpRetryConfig/tcpRetryConfig.ino +154 -0
  18. package/keywords.txt +3 -0
  19. package/library.json +4 -1
  20. package/library.properties +1 -1
  21. package/package.json +3 -3
  22. package/src/AlteriomPainlessMesh.h +6 -14
  23. package/src/arduino/wifi.hpp +352 -114
  24. package/src/connection.cpp +10 -0
  25. package/src/painlessMesh.h +2 -15
  26. package/src/painlessTaskOptions.h +9 -0
  27. package/src/painlessmesh/buffer.hpp +4 -1
  28. package/src/painlessmesh/configuration.hpp +13 -2
  29. package/src/painlessmesh/connection.hpp +36 -21
  30. package/src/painlessmesh/gateway.hpp +0 -1061
  31. package/src/painlessmesh/mesh.hpp +102 -107
  32. package/src/painlessmesh/message_queue.hpp +25 -15
  33. package/src/painlessmesh/metrics.hpp +2 -262
  34. package/src/painlessmesh/plugin.hpp +27 -5
  35. package/src/painlessmesh/tcp.hpp +158 -29
  36. package/src/painlessmesh/validation.hpp +0 -143
  37. package/docs/README.md +0 -132
  38. package/docs/alteriom/overview.md +0 -531
  39. package/docs/api/core-api.md +0 -607
  40. package/docs/api/shared-gateway.md +0 -1207
  41. package/docs/architecture/mesh-architecture.md +0 -399
  42. package/docs/architecture/plugin-system.md +0 -517
  43. package/docs/getting-started/arduino-manual-install.md +0 -313
  44. package/docs/getting-started/first-mesh.md +0 -410
  45. package/docs/getting-started/installation.md +0 -275
  46. package/docs/getting-started/quickstart.md +0 -158
  47. package/docs/troubleshooting/common-issues.md +0 -679
  48. package/docs/troubleshooting/debugging.md +0 -455
  49. package/docs/troubleshooting/external-device-connection.md +0 -283
  50. package/docs/troubleshooting/faq.md +0 -574
  51. package/docs/tutorials/basic-examples.md +0 -718
@@ -0,0 +1,361 @@
1
+ //************************************************************
2
+ // Mock HTTP Server Integration Example
3
+ //
4
+ // This example demonstrates how to use the mock HTTP server
5
+ // for testing sendToInternet() functionality without requiring
6
+ // actual Internet connectivity.
7
+ //
8
+ // Setup:
9
+ // 1. Start the mock server on your development machine:
10
+ // cd test/mock-http-server
11
+ // python3 server.py
12
+ //
13
+ // 2. Update MOCK_SERVER_IP below with your computer's IP address
14
+ //
15
+ // 3. Upload this sketch to your ESP32/ESP8266
16
+ //
17
+ // 4. Watch the serial output and mock server logs
18
+ //
19
+ // The sketch will automatically run through various test scenarios
20
+ // and report pass/fail results for each test case.
21
+ //************************************************************
22
+
23
+ #include "painlessMesh.h"
24
+
25
+ // ============================================
26
+ // Configuration
27
+ // ============================================
28
+ #define MESH_PREFIX "TestMesh"
29
+ #define MESH_PASSWORD "testpass123"
30
+ #define MESH_PORT 5555
31
+
32
+ // Router credentials (for bridge node)
33
+ #define ROUTER_SSID "YourRouterSSID"
34
+ #define ROUTER_PASSWORD "YourRouterPassword"
35
+
36
+ // Mock HTTP Server Configuration
37
+ // Replace with your computer's IP address where mock server is running
38
+ #define MOCK_SERVER_IP "192.168.1.100" // ← CHANGE THIS
39
+ #define MOCK_SERVER_PORT 8080
40
+
41
+ // Set to true if this node should be the bridge
42
+ #define IS_BRIDGE true
43
+
44
+ // ============================================
45
+ // Global Objects
46
+ // ============================================
47
+ Scheduler userScheduler;
48
+ painlessMesh mesh;
49
+
50
+ // Test tracking
51
+ int totalTests = 0;
52
+ int passedTests = 0;
53
+ int failedTests = 0;
54
+
55
+ // ============================================
56
+ // Helper Functions
57
+ // ============================================
58
+
59
+ String getMockServerUrl(const String& endpoint) {
60
+ return String("http://") + MOCK_SERVER_IP + ":" + String(MOCK_SERVER_PORT) + endpoint;
61
+ }
62
+
63
+ void recordTestResult(const String& testName, bool passed) {
64
+ totalTests++;
65
+ if (passed) {
66
+ passedTests++;
67
+ Serial.printf("✓ PASS: %s\n", testName.c_str());
68
+ } else {
69
+ failedTests++;
70
+ Serial.printf("✗ FAIL: %s\n", testName.c_str());
71
+ }
72
+ }
73
+
74
+ void printTestSummary() {
75
+ Serial.println("\n========================================");
76
+ Serial.println("Test Summary");
77
+ Serial.println("========================================");
78
+ Serial.printf("Total Tests: %d\n", totalTests);
79
+ Serial.printf("Passed: %d\n", passedTests);
80
+ Serial.printf("Failed: %d\n", failedTests);
81
+ Serial.printf("Success Rate: %.1f%%\n", (totalTests > 0) ? (100.0 * passedTests / totalTests) : 0.0);
82
+ Serial.println("========================================\n");
83
+ }
84
+
85
+ // ============================================
86
+ // Test Cases
87
+ // ============================================
88
+
89
+ /**
90
+ * Test Case 1: HTTP 200 Success
91
+ * Expected: success=true, status=200
92
+ */
93
+ void testHttp200Success() {
94
+ Serial.println("\n[Test 1] HTTP 200 Success Response");
95
+
96
+ String url = getMockServerUrl("/status/200");
97
+ Serial.printf("URL: %s\n", url.c_str());
98
+
99
+ mesh.sendToInternet(url, "", [](bool success, uint16_t status, String error) {
100
+ bool testPassed = (success && status == 200);
101
+ recordTestResult("HTTP 200 Success", testPassed);
102
+
103
+ if (!testPassed) {
104
+ Serial.printf(" Expected: success=true, status=200\n");
105
+ Serial.printf(" Got: success=%s, status=%d, error=%s\n",
106
+ success ? "true" : "false", status, error.c_str());
107
+ }
108
+ });
109
+ }
110
+
111
+ /**
112
+ * Test Case 2: HTTP 203 Non-Authoritative
113
+ * Expected: success=false (per Issue #336 fix)
114
+ */
115
+ void testHttp203Failure() {
116
+ Serial.println("\n[Test 2] HTTP 203 Non-Authoritative (should fail)");
117
+
118
+ String url = getMockServerUrl("/status/203");
119
+ Serial.printf("URL: %s\n", url.c_str());
120
+
121
+ mesh.sendToInternet(url, "", [](bool success, uint16_t status, String error) {
122
+ // HTTP 203 should be treated as failure (cached/proxied response)
123
+ bool testPassed = (!success && status == 203);
124
+ recordTestResult("HTTP 203 treated as failure", testPassed);
125
+
126
+ if (!testPassed) {
127
+ Serial.printf(" Expected: success=false, status=203\n");
128
+ Serial.printf(" Got: success=%s, status=%d\n",
129
+ success ? "true" : "false", status);
130
+ }
131
+ });
132
+ }
133
+
134
+ /**
135
+ * Test Case 3: HTTP 404 Not Found
136
+ * Expected: success=false, status=404
137
+ */
138
+ void testHttp404NotFound() {
139
+ Serial.println("\n[Test 3] HTTP 404 Not Found");
140
+
141
+ String url = getMockServerUrl("/status/404");
142
+ Serial.printf("URL: %s\n", url.c_str());
143
+
144
+ mesh.sendToInternet(url, "", [](bool success, uint16_t status, String error) {
145
+ bool testPassed = (!success && status == 404);
146
+ recordTestResult("HTTP 404 Not Found", testPassed);
147
+
148
+ if (!testPassed) {
149
+ Serial.printf(" Expected: success=false, status=404\n");
150
+ Serial.printf(" Got: success=%s, status=%d\n",
151
+ success ? "true" : "false", status);
152
+ }
153
+ });
154
+ }
155
+
156
+ /**
157
+ * Test Case 4: HTTP 500 Internal Server Error
158
+ * Expected: success=false, status=500
159
+ */
160
+ void testHttp500ServerError() {
161
+ Serial.println("\n[Test 4] HTTP 500 Internal Server Error");
162
+
163
+ String url = getMockServerUrl("/status/500");
164
+ Serial.printf("URL: %s\n", url.c_str());
165
+
166
+ mesh.sendToInternet(url, "", [](bool success, uint16_t status, String error) {
167
+ bool testPassed = (!success && status == 500);
168
+ recordTestResult("HTTP 500 Server Error", testPassed);
169
+
170
+ if (!testPassed) {
171
+ Serial.printf(" Expected: success=false, status=500\n");
172
+ Serial.printf(" Got: success=%s, status=%d\n",
173
+ success ? "true" : "false", status);
174
+ }
175
+ });
176
+ }
177
+
178
+ /**
179
+ * Test Case 5: WhatsApp API Simulation
180
+ * Expected: success=true, status=200
181
+ */
182
+ void testWhatsAppApiSimulation() {
183
+ Serial.println("\n[Test 5] WhatsApp API Simulation");
184
+
185
+ String url = getMockServerUrl("/whatsapp");
186
+ url += "?phone=%2B1234567890";
187
+ url += "&apikey=test_key";
188
+ url += "&text=Test%20message%20from%20ESP";
189
+
190
+ Serial.printf("URL: %s\n", url.c_str());
191
+
192
+ mesh.sendToInternet(url, "", [](bool success, uint16_t status, String error) {
193
+ bool testPassed = (success && status == 200);
194
+ recordTestResult("WhatsApp API Simulation", testPassed);
195
+
196
+ if (!testPassed) {
197
+ Serial.printf(" Expected: success=true, status=200\n");
198
+ Serial.printf(" Got: success=%s, status=%d, error=%s\n",
199
+ success ? "true" : "false", status, error.c_str());
200
+ }
201
+ });
202
+ }
203
+
204
+ /**
205
+ * Test Case 6: Delayed Response (2 seconds)
206
+ * Expected: success=true after 2+ seconds
207
+ */
208
+ void testDelayedResponse() {
209
+ Serial.println("\n[Test 6] Delayed Response (2 seconds)");
210
+
211
+ String url = getMockServerUrl("/delay/2");
212
+ Serial.printf("URL: %s\n", url.c_str());
213
+
214
+ unsigned long startTime = millis();
215
+
216
+ mesh.sendToInternet(url, "", [startTime](bool success, uint16_t status, String error) {
217
+ unsigned long elapsed = millis() - startTime;
218
+ bool testPassed = (success && status == 200 && elapsed >= 2000);
219
+ recordTestResult("Delayed Response (2s)", testPassed);
220
+
221
+ Serial.printf(" Response time: %lu ms\n", elapsed);
222
+
223
+ if (!testPassed) {
224
+ Serial.printf(" Expected: success=true, elapsed >= 2000ms\n");
225
+ Serial.printf(" Got: success=%s, elapsed=%lu ms\n",
226
+ success ? "true" : "false", elapsed);
227
+ }
228
+ });
229
+ }
230
+
231
+ /**
232
+ * Test Case 7: Echo Endpoint (POST with payload)
233
+ * Expected: success=true, server echoes back our data
234
+ */
235
+ void testEchoEndpoint() {
236
+ Serial.println("\n[Test 7] Echo Endpoint with JSON Payload");
237
+
238
+ String url = getMockServerUrl("/echo");
239
+ String payload = "{\"sensor\":\"temperature\",\"value\":25.5,\"unit\":\"celsius\"}";
240
+
241
+ Serial.printf("URL: %s\n", url.c_str());
242
+ Serial.printf("Payload: %s\n", payload.c_str());
243
+
244
+ mesh.sendToInternet(url, payload, [](bool success, uint16_t status, String error) {
245
+ bool testPassed = (success && status == 200);
246
+ recordTestResult("Echo Endpoint", testPassed);
247
+
248
+ if (!testPassed) {
249
+ Serial.printf(" Expected: success=true, status=200\n");
250
+ Serial.printf(" Got: success=%s, status=%d\n",
251
+ success ? "true" : "false", status);
252
+ }
253
+ });
254
+ }
255
+
256
+ // ============================================
257
+ // Task to Run All Tests
258
+ // ============================================
259
+
260
+ void runAllTests() {
261
+ Serial.println("\n\n");
262
+ Serial.println("========================================");
263
+ Serial.println("Starting Mock HTTP Server Test Suite");
264
+ Serial.println("========================================");
265
+ Serial.printf("Mock Server: http://%s:%d\n", MOCK_SERVER_IP, MOCK_SERVER_PORT);
266
+ Serial.println("========================================\n");
267
+
268
+ // Wait a bit for mesh to stabilize
269
+ delay(5000);
270
+
271
+ // Run all test cases with delays between them
272
+ testHttp200Success();
273
+ delay(2000);
274
+
275
+ testHttp203Failure();
276
+ delay(2000);
277
+
278
+ testHttp404NotFound();
279
+ delay(2000);
280
+
281
+ testHttp500ServerError();
282
+ delay(2000);
283
+
284
+ testWhatsAppApiSimulation();
285
+ delay(2000);
286
+
287
+ testDelayedResponse();
288
+ delay(4000); // Extra delay for the delayed response test
289
+
290
+ testEchoEndpoint();
291
+ delay(2000);
292
+
293
+ // Print summary after all tests complete
294
+ delay(5000);
295
+ printTestSummary();
296
+ }
297
+
298
+ Task taskRunTests(TASK_ONCE, TASK_IMMEDIATE, &runAllTests, &userScheduler);
299
+
300
+ // ============================================
301
+ // Setup Function
302
+ // ============================================
303
+
304
+ void setup() {
305
+ Serial.begin(115200);
306
+ delay(1000);
307
+
308
+ Serial.println("\n\n");
309
+ Serial.println("================================================");
310
+ Serial.println(" Mock HTTP Server Integration Example");
311
+ Serial.println(" painlessMesh sendToInternet Testing");
312
+ Serial.println("================================================\n");
313
+
314
+ // Configure mesh
315
+ mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
316
+
317
+ bool success = false;
318
+
319
+ #if IS_BRIDGE
320
+ // Initialize as bridge with router connection
321
+ Serial.println("Mode: BRIDGE NODE\n");
322
+ success = mesh.initAsBridge(
323
+ MESH_PREFIX, MESH_PASSWORD,
324
+ ROUTER_SSID, ROUTER_PASSWORD,
325
+ &userScheduler, MESH_PORT
326
+ );
327
+
328
+ if (success) {
329
+ Serial.println("✓ Bridge initialized successfully");
330
+ } else {
331
+ Serial.println("✗ Bridge init failed - falling back to regular mesh");
332
+ mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
333
+ }
334
+ #else
335
+ // Initialize as regular mesh node
336
+ Serial.println("Mode: REGULAR NODE\n");
337
+ mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
338
+ success = true;
339
+ #endif
340
+
341
+ // Enable sendToInternet API
342
+ mesh.enableSendToInternet();
343
+
344
+ Serial.println("================================================");
345
+ Serial.printf("Node ID: %u\n", mesh.getNodeId());
346
+ Serial.printf("Is Bridge: %s\n", mesh.isBridge() ? "YES" : "NO");
347
+ Serial.println("================================================\n");
348
+
349
+ // Schedule test run
350
+ Serial.println("Tests will start in 10 seconds...\n");
351
+ taskRunTests.setInterval(10000); // Start after 10 seconds
352
+ taskRunTests.enable();
353
+ }
354
+
355
+ // ============================================
356
+ // Main Loop
357
+ // ============================================
358
+
359
+ void loop() {
360
+ mesh.update();
361
+ }