@alteriom/painlessmesh 1.6.1

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 (80) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/LICENSE +674 -0
  3. package/README.md +434 -0
  4. package/RELEASE_GUIDE.md +419 -0
  5. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +176 -0
  6. package/docs/README.md +71 -0
  7. package/docs/alteriom/overview.md +508 -0
  8. package/docs/api/core-api.md +607 -0
  9. package/docs/architecture/mesh-architecture.md +379 -0
  10. package/docs/architecture/plugin-system.md +517 -0
  11. package/docs/getting-started/first-mesh.md +410 -0
  12. package/docs/getting-started/installation.md +275 -0
  13. package/docs/getting-started/quickstart.md +158 -0
  14. package/docs/improvements/README.md +69 -0
  15. package/docs/troubleshooting/common-issues.md +521 -0
  16. package/docs/troubleshooting/faq.md +473 -0
  17. package/docs/tutorials/basic-examples.md +718 -0
  18. package/docs/wiki/API-Reference.md +246 -0
  19. package/docs/wiki/Complete-Documentation.md +123 -0
  20. package/examples/alteriom/README.md +82 -0
  21. package/examples/alteriom/alteriom.ino +186 -0
  22. package/examples/alteriom/alteriom_sensor_node.ino +184 -0
  23. package/examples/alteriom/alteriom_sensor_package.hpp +128 -0
  24. package/examples/alteriom/improved_sensor_node.ino +246 -0
  25. package/examples/alteriom/platformio.ini +25 -0
  26. package/examples/basic/basic.ino +66 -0
  27. package/examples/basic/platformio.ini +25 -0
  28. package/examples/bridge/bridge.ino +51 -0
  29. package/examples/bridge/platformio.ini +25 -0
  30. package/examples/echoNode/echoNode.ino +33 -0
  31. package/examples/echoNode/platformio.ini +25 -0
  32. package/examples/logClient/logClient.ino +109 -0
  33. package/examples/logClient/platformio.ini +25 -0
  34. package/examples/logServer/logServer.ino +81 -0
  35. package/examples/logServer/platformio.ini +25 -0
  36. package/examples/mqttBridge/mqttBridge.ino +118 -0
  37. package/examples/mqttBridge/platformio.ini +26 -0
  38. package/examples/namedMesh/namedMesh.ino +97 -0
  39. package/examples/namedMesh/platformio.ini +25 -0
  40. package/examples/otaReceiver/otaReceiver.ino +79 -0
  41. package/examples/otaReceiver/platformio.ini +25 -0
  42. package/examples/otaSender/nodemcu32s_connections.JPG +0 -0
  43. package/examples/otaSender/otaSender.ino +151 -0
  44. package/examples/otaSender/platformio.ini +25 -0
  45. package/examples/startHere/platformio.ini +25 -0
  46. package/examples/startHere/startHere.ino +159 -0
  47. package/examples/webServer/platformio.ini +27 -0
  48. package/examples/webServer/webServer.ino +89 -0
  49. package/keywords.txt +49 -0
  50. package/library.json +34 -0
  51. package/library.properties +11 -0
  52. package/package.json +78 -0
  53. package/src/AlteriomPainlessMesh.h +98 -0
  54. package/src/arduino/wifi.hpp +365 -0
  55. package/src/boost/asynctcp.hpp +279 -0
  56. package/src/painlessMesh.h +70 -0
  57. package/src/painlessMeshSTA.cpp +236 -0
  58. package/src/painlessMeshSTA.h +58 -0
  59. package/src/painlessTaskOptions.h +4 -0
  60. package/src/painlessmesh/base64.hpp +111 -0
  61. package/src/painlessmesh/buffer.hpp +229 -0
  62. package/src/painlessmesh/callback.hpp +91 -0
  63. package/src/painlessmesh/configuration.hpp +77 -0
  64. package/src/painlessmesh/connection.hpp +192 -0
  65. package/src/painlessmesh/layout.hpp +188 -0
  66. package/src/painlessmesh/logger.hpp +158 -0
  67. package/src/painlessmesh/memory.hpp +120 -0
  68. package/src/painlessmesh/mesh.hpp +560 -0
  69. package/src/painlessmesh/metrics.hpp +323 -0
  70. package/src/painlessmesh/ntp.hpp +263 -0
  71. package/src/painlessmesh/ota.hpp +553 -0
  72. package/src/painlessmesh/plugin.hpp +188 -0
  73. package/src/painlessmesh/protocol.hpp +813 -0
  74. package/src/painlessmesh/router.hpp +322 -0
  75. package/src/painlessmesh/tcp.hpp +71 -0
  76. package/src/painlessmesh/validation.hpp +239 -0
  77. package/src/plugin/performance.hpp +214 -0
  78. package/src/plugin/remote.hpp +64 -0
  79. package/src/scheduler.cpp +10 -0
  80. package/src/wifi.cpp +2 -0
@@ -0,0 +1,508 @@
1
+ # Alteriom Extensions Overview
2
+
3
+ The Alteriom extensions provide production-ready, type-safe packages for common IoT scenarios. These extensions demonstrate best practices for the painlessMesh plugin system while providing immediately useful functionality for sensor networks, device control, and system monitoring.
4
+
5
+ ## What are Alteriom Extensions?
6
+
7
+ Alteriom extensions are pre-built painlessMesh packages that handle common IoT communication patterns:
8
+
9
+ - **Environmental Monitoring**: Temperature, humidity, pressure sensors
10
+ - **Device Control**: Commands for actuators, displays, relays
11
+ - **Health Monitoring**: Device status, diagnostics, and telemetry
12
+ - **Type Safety**: Compile-time validation and automatic serialization
13
+ - **Production Ready**: Tested, documented, and optimized implementations
14
+
15
+ ## Package Types
16
+
17
+ ### SensorPackage (Type 200)
18
+ For broadcasting environmental sensor data across the mesh.
19
+
20
+ ```cpp
21
+ alteriom::SensorPackage sensor;
22
+ sensor.temperature = 23.5;
23
+ sensor.humidity = 65.0;
24
+ sensor.pressure = 1013.25;
25
+ sensor.sensorId = 1001;
26
+ sensor.timestamp = mesh.getNodeTime();
27
+ sensor.batteryLevel = 85;
28
+
29
+ mesh.sendPackage(&sensor);
30
+ ```
31
+
32
+ **Use Cases:**
33
+ - Weather stations
34
+ - Environmental monitoring
35
+ - HVAC system feedback
36
+ - Greenhouse automation
37
+ - Industrial sensor networks
38
+
39
+ ### CommandPackage (Type 201)
40
+ For sending control commands to specific devices.
41
+
42
+ ```cpp
43
+ alteriom::CommandPackage cmd;
44
+ cmd.dest = targetNodeId;
45
+ cmd.command = 1; // LED_CONTROL
46
+ cmd.targetDevice = 100; // LED strip ID
47
+ cmd.parameters = "{\"brightness\":75,\"color\":\"blue\"}";
48
+ cmd.commandId = generateCommandId();
49
+
50
+ mesh.sendPackage(&cmd);
51
+ ```
52
+
53
+ **Use Cases:**
54
+ - Remote device control
55
+ - Actuator management
56
+ - Display updates
57
+ - System configuration
58
+ - Automation triggers
59
+
60
+ ### StatusPackage (Type 202)
61
+ For broadcasting device health and operational status.
62
+
63
+ ```cpp
64
+ alteriom::StatusPackage status;
65
+ status.deviceStatus = 1; // OPERATIONAL
66
+ status.uptime = millis() / 1000;
67
+ status.freeMemory = ESP.getFreeHeap();
68
+ status.wifiStrength = WiFi.RSSI();
69
+ status.firmwareVersion = "1.2.3";
70
+
71
+ mesh.sendPackage(&status);
72
+ ```
73
+
74
+ **Use Cases:**
75
+ - System monitoring
76
+ - Predictive maintenance
77
+ - Network diagnostics
78
+ - Performance tracking
79
+ - Remote troubleshooting
80
+
81
+ ## Key Features
82
+
83
+ ### Type Safety
84
+ Compile-time validation prevents common messaging errors:
85
+
86
+ ```cpp
87
+ // Compile error if field types don't match
88
+ sensor.temperature = "invalid"; // ❌ Compiler error
89
+ sensor.temperature = 25.0; // ✅ Correct
90
+
91
+ // IDE autocomplete for all fields
92
+ sensor.| // IDE shows: temperature, humidity, pressure, etc.
93
+ ```
94
+
95
+ ### Automatic Serialization
96
+ No manual JSON handling required:
97
+
98
+ ```cpp
99
+ // Automatic serialization to JSON
100
+ mesh.sendPackage(&sensor);
101
+
102
+ // Automatic deserialization from JSON
103
+ mesh.onPackage(200, [](protocol::Variant& variant) {
104
+ alteriom::SensorPackage received = variant.to<alteriom::SensorPackage>();
105
+ // All fields automatically populated
106
+ });
107
+ ```
108
+
109
+ ### Cross-Platform Compatibility
110
+ Works on ESP32, ESP8266, and desktop platforms:
111
+
112
+ ```cpp
113
+ // TSTRING adapts to platform
114
+ #ifdef ESP32
115
+ // Uses Arduino String class
116
+ #else
117
+ // Uses std::string on desktop
118
+ #endif
119
+ ```
120
+
121
+ ### Memory Optimization
122
+ Efficient memory usage for resource-constrained devices:
123
+
124
+ ```cpp
125
+ // Accurate buffer sizing
126
+ size_t bufferSize = sensor.jsonObjectSize();
127
+
128
+ // Minimal memory footprint
129
+ // No unnecessary string copies or allocations
130
+ ```
131
+
132
+ ## Architecture Integration
133
+
134
+ ### Plugin System
135
+ Alteriom packages integrate seamlessly with painlessMesh's plugin architecture:
136
+
137
+ ```
138
+ Application Layer (Your Code)
139
+
140
+ Alteriom Packages (SensorPackage, CommandPackage, StatusPackage)
141
+
142
+ painlessMesh Plugin System (SinglePackage, BroadcastPackage)
143
+
144
+ painlessMesh Core (Mesh, Protocol, Network)
145
+ ```
146
+
147
+ ### Message Flow
148
+ ```
149
+ Sensor Reading → SensorPackage → JSON → Mesh Network → JSON → SensorPackage → Handler
150
+ ```
151
+
152
+ ### Type ID Allocation
153
+ Alteriom uses reserved type ID range 200-299:
154
+
155
+ ```cpp
156
+ enum AlteriomTypes {
157
+ ALTERIOM_SENSOR = 200, // SensorPackage
158
+ ALTERIOM_COMMAND = 201, // CommandPackage
159
+ ALTERIOM_STATUS = 202, // StatusPackage
160
+ // 203-299 reserved for future Alteriom packages
161
+ };
162
+ ```
163
+
164
+ ## Getting Started
165
+
166
+ ### 1. Include Alteriom Headers
167
+
168
+ ```cpp
169
+ #include "painlessMesh.h"
170
+ #include "examples/alteriom/alteriom_sensor_package.hpp"
171
+
172
+ using namespace alteriom; // For convenience
173
+ ```
174
+
175
+ ### 2. Register Package Handlers
176
+
177
+ ```cpp
178
+ void setup() {
179
+ mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
180
+
181
+ // Register handlers for Alteriom packages
182
+ mesh.onPackage(ALTERIOM_SENSOR, handleSensorData);
183
+ mesh.onPackage(ALTERIOM_COMMAND, handleCommand);
184
+ mesh.onPackage(ALTERIOM_STATUS, handleStatus);
185
+ }
186
+ ```
187
+
188
+ ### 3. Implement Handlers
189
+
190
+ ```cpp
191
+ void handleSensorData(protocol::Variant& variant) {
192
+ SensorPackage sensor = variant.to<SensorPackage>();
193
+
194
+ Serial.printf("Sensor %u: T=%.1f°C, H=%.1f%%, P=%.1f hPa\n",
195
+ sensor.sensorId, sensor.temperature,
196
+ sensor.humidity, sensor.pressure);
197
+
198
+ // Process sensor data (store, analyze, forward, etc.)
199
+ if (sensor.temperature > 30.0) {
200
+ triggerCooling();
201
+ }
202
+ }
203
+
204
+ void handleCommand(protocol::Variant& variant) {
205
+ CommandPackage cmd = variant.to<CommandPackage>();
206
+
207
+ if (cmd.dest != mesh.getNodeId()) {
208
+ return; // Not for this node
209
+ }
210
+
211
+ Serial.printf("Command %u for device %u: %u\n",
212
+ cmd.commandId, cmd.targetDevice, cmd.command);
213
+
214
+ // Execute command
215
+ executeDeviceCommand(cmd);
216
+
217
+ // Send acknowledgment
218
+ sendCommandAcknowledgment(cmd);
219
+ }
220
+ ```
221
+
222
+ ### 4. Send Packages
223
+
224
+ ```cpp
225
+ // Send sensor data every 30 seconds
226
+ Task taskSensorData(30000, TASK_FOREVER, [](){
227
+ SensorPackage sensor;
228
+ sensor.from = mesh.getNodeId();
229
+ sensor.temperature = readTemperature();
230
+ sensor.humidity = readHumidity();
231
+ sensor.pressure = readPressure();
232
+ sensor.sensorId = SENSOR_ID;
233
+ sensor.timestamp = mesh.getNodeTime();
234
+ sensor.batteryLevel = readBatteryLevel();
235
+
236
+ mesh.sendPackage(&sensor);
237
+ });
238
+ ```
239
+
240
+ ## Advanced Usage
241
+
242
+ ### Custom Command Types
243
+
244
+ Define application-specific command types:
245
+
246
+ ```cpp
247
+ enum DeviceCommands {
248
+ LED_CONTROL = 1,
249
+ SERVO_POSITION = 2,
250
+ RELAY_SWITCH = 3,
251
+ DISPLAY_UPDATE = 4,
252
+ SENSOR_CALIBRATION = 5
253
+ };
254
+
255
+ void executeDeviceCommand(const CommandPackage& cmd) {
256
+ switch(cmd.command) {
257
+ case LED_CONTROL:
258
+ handleLEDCommand(cmd);
259
+ break;
260
+ case SERVO_POSITION:
261
+ handleServoCommand(cmd);
262
+ break;
263
+ // ... other commands
264
+ }
265
+ }
266
+ ```
267
+
268
+ ### Command Parameters
269
+
270
+ Use JSON parameters for complex commands:
271
+
272
+ ```cpp
273
+ void handleLEDCommand(const CommandPackage& cmd) {
274
+ // Parse JSON parameters
275
+ DynamicJsonDocument doc(256);
276
+ deserializeJson(doc, cmd.parameters);
277
+
278
+ int brightness = doc["brightness"];
279
+ String color = doc["color"];
280
+ int duration = doc["duration"];
281
+
282
+ // Execute LED control
283
+ setLEDColor(color);
284
+ setLEDBrightness(brightness);
285
+ if (duration > 0) {
286
+ scheduleAutoOff(duration);
287
+ }
288
+ }
289
+ ```
290
+
291
+ ### Status Monitoring
292
+
293
+ Implement comprehensive device monitoring:
294
+
295
+ ```cpp
296
+ void sendStatusUpdate() {
297
+ StatusPackage status;
298
+ status.from = mesh.getNodeId();
299
+ status.deviceStatus = getDeviceStatus();
300
+ status.uptime = millis() / 1000;
301
+ status.freeMemory = ESP.getFreeHeap();
302
+ status.wifiStrength = WiFi.RSSI();
303
+ status.firmwareVersion = FIRMWARE_VERSION;
304
+
305
+ // Add custom diagnostics
306
+ if (ESP.getFreeHeap() < 10000) {
307
+ status.deviceStatus |= STATUS_LOW_MEMORY;
308
+ }
309
+ if (WiFi.RSSI() < -80) {
310
+ status.deviceStatus |= STATUS_WEAK_SIGNAL;
311
+ }
312
+
313
+ mesh.sendPackage(&status);
314
+ }
315
+ ```
316
+
317
+ ### Error Handling
318
+
319
+ Implement robust error handling:
320
+
321
+ ```cpp
322
+ void handleSensorData(protocol::Variant& variant) {
323
+ try {
324
+ SensorPackage sensor = variant.to<SensorPackage>();
325
+
326
+ // Validate sensor data
327
+ if (!isValidSensorReading(sensor)) {
328
+ Serial.printf("Invalid sensor data from node %u\n", sensor.from);
329
+ return;
330
+ }
331
+
332
+ // Check data age
333
+ uint32_t age = mesh.getNodeTime() - sensor.timestamp;
334
+ if (age > MAX_DATA_AGE) {
335
+ Serial.printf("Stale sensor data (age: %u µs)\n", age);
336
+ return;
337
+ }
338
+
339
+ processSensorData(sensor);
340
+
341
+ } catch (const std::exception& e) {
342
+ Serial.printf("Error processing sensor data: %s\n", e.what());
343
+ }
344
+ }
345
+ ```
346
+
347
+ ## Integration Patterns
348
+
349
+ ### Sensor Network Pattern
350
+
351
+ Central collector with multiple sensor nodes:
352
+
353
+ ```cpp
354
+ class SensorCollector {
355
+ private:
356
+ std::map<uint32_t, SensorData> sensorReadings;
357
+
358
+ public:
359
+ void setup() {
360
+ mesh.onPackage(ALTERIOM_SENSOR, [this](protocol::Variant& variant) {
361
+ SensorPackage sensor = variant.to<SensorPackage>();
362
+ storeSensorReading(sensor);
363
+ return false;
364
+ });
365
+ }
366
+
367
+ void storeSensorReading(const SensorPackage& sensor) {
368
+ sensorReadings[sensor.from] = {
369
+ sensor.temperature,
370
+ sensor.humidity,
371
+ sensor.pressure,
372
+ sensor.timestamp
373
+ };
374
+
375
+ // Trigger analysis
376
+ analyzeEnvironmentalData();
377
+ }
378
+ };
379
+ ```
380
+
381
+ ### Command and Control Pattern
382
+
383
+ Central controller managing multiple devices:
384
+
385
+ ```cpp
386
+ class DeviceController {
387
+ private:
388
+ std::map<uint32_t, DeviceInfo> devices;
389
+
390
+ public:
391
+ void controlDevice(uint32_t nodeId, uint32_t deviceId,
392
+ uint8_t command, const String& parameters) {
393
+ CommandPackage cmd;
394
+ cmd.dest = nodeId;
395
+ cmd.command = command;
396
+ cmd.targetDevice = deviceId;
397
+ cmd.parameters = parameters;
398
+ cmd.commandId = generateCommandId();
399
+
400
+ mesh.sendPackage(&cmd);
401
+
402
+ // Track pending command
403
+ pendingCommands[cmd.commandId] = {nodeId, millis()};
404
+ }
405
+
406
+ void handleCommandAck(const CommandPackage& ack) {
407
+ auto it = pendingCommands.find(ack.commandId);
408
+ if (it != pendingCommands.end()) {
409
+ Serial.printf("Command %u acknowledged by node %u\n",
410
+ ack.commandId, ack.from);
411
+ pendingCommands.erase(it);
412
+ }
413
+ }
414
+ };
415
+ ```
416
+
417
+ ### Health Monitoring Pattern
418
+
419
+ Network-wide device health monitoring:
420
+
421
+ ```cpp
422
+ class HealthMonitor {
423
+ private:
424
+ std::map<uint32_t, DeviceHealth> deviceHealth;
425
+
426
+ public:
427
+ void setup() {
428
+ mesh.onPackage(ALTERIOM_STATUS, [this](protocol::Variant& variant) {
429
+ StatusPackage status = variant.to<StatusPackage>();
430
+ updateDeviceHealth(status);
431
+ return false;
432
+ });
433
+
434
+ // Check for unhealthy devices every minute
435
+ userScheduler.addTask(Task(60000, TASK_FOREVER, [this]() {
436
+ checkDeviceHealth();
437
+ }));
438
+ }
439
+
440
+ void updateDeviceHealth(const StatusPackage& status) {
441
+ deviceHealth[status.from] = {
442
+ status.deviceStatus,
443
+ status.uptime,
444
+ status.freeMemory,
445
+ status.wifiStrength,
446
+ mesh.getNodeTime() // Last seen
447
+ };
448
+ }
449
+
450
+ void checkDeviceHealth() {
451
+ uint32_t now = mesh.getNodeTime();
452
+
453
+ for (auto& [nodeId, health] : deviceHealth) {
454
+ uint32_t timeSinceLastSeen = now - health.lastSeen;
455
+
456
+ if (timeSinceLastSeen > DEVICE_TIMEOUT) {
457
+ Serial.printf("Device %u appears offline\n", nodeId);
458
+ triggerAlert(nodeId, "Device offline");
459
+ }
460
+
461
+ if (health.freeMemory < LOW_MEMORY_THRESHOLD) {
462
+ Serial.printf("Device %u low memory: %u bytes\n",
463
+ nodeId, health.freeMemory);
464
+ triggerAlert(nodeId, "Low memory");
465
+ }
466
+ }
467
+ }
468
+ };
469
+ ```
470
+
471
+ ## Best Practices
472
+
473
+ ### Performance Optimization
474
+
475
+ 1. **Batch sensor readings** when possible
476
+ 2. **Use appropriate message frequency** (don't spam the network)
477
+ 3. **Implement message filtering** to avoid processing irrelevant data
478
+ 4. **Monitor memory usage** especially on ESP8266
479
+
480
+ ### Reliability
481
+
482
+ 1. **Validate all received data** before processing
483
+ 2. **Implement timeouts** for commands and responses
484
+ 3. **Handle network partitions** gracefully
485
+ 4. **Add retry logic** for critical commands
486
+
487
+ ### Security
488
+
489
+ 1. **Validate message sources** in handlers
490
+ 2. **Sanitize command parameters** before execution
491
+ 3. **Implement rate limiting** for commands
492
+ 4. **Consider encryption** for sensitive data
493
+
494
+ ### Testing
495
+
496
+ 1. **Test with realistic network loads**
497
+ 2. **Simulate node failures** and recovery
498
+ 3. **Validate under memory pressure**
499
+ 4. **Test with maximum expected node count**
500
+
501
+ ## Next Steps
502
+
503
+ - Learn about [Sensor Packages](sensor-packages.md) in detail
504
+ - Explore [Command System](command-system.md) implementation
505
+ - Study [Status Monitoring](status-monitoring.md) patterns
506
+ - See [Tutorial Examples](../tutorials/sensor-networks.md) for hands-on practice
507
+
508
+ The Alteriom extensions provide a solid foundation for building robust IoT applications with painlessMesh. They demonstrate production-ready patterns while remaining flexible enough to adapt to your specific needs.