@alteriom/painlessmesh 1.6.1 → 1.7.2

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 (129) hide show
  1. package/CHANGELOG.md +380 -143
  2. package/LICENSE +674 -674
  3. package/README.md +477 -434
  4. package/RELEASE_GUIDE.md +504 -418
  5. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +175 -175
  6. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +1062 -0
  7. package/docs/MESH_TOPOLOGY_GUIDE.md +992 -0
  8. package/docs/MESH_TOPOLOGY_PROGRESS.md +422 -0
  9. package/docs/MQTT_BRIDGE_COMMANDS.md +894 -0
  10. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +324 -0
  11. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +576 -0
  12. package/docs/MQTT_SCHEMA_COMPLIANCE.md +285 -0
  13. package/docs/MQTT_SCHEMA_PROPOSALS.md +446 -0
  14. package/docs/MQTT_SCHEMA_REVIEW.md +690 -0
  15. package/docs/OTA_COMMANDS_REFERENCE.md +554 -0
  16. package/docs/PHASE1_GUIDE.md +349 -0
  17. package/docs/PHASE2_GUIDE.md +543 -0
  18. package/docs/README.md +77 -70
  19. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +222 -0
  20. package/docs/alteriom/overview.md +507 -507
  21. package/docs/api/core-api.md +606 -606
  22. package/docs/architecture/mesh-architecture.md +378 -378
  23. package/docs/architecture/plugin-system.md +516 -516
  24. package/docs/getting-started/first-mesh.md +409 -409
  25. package/docs/getting-started/installation.md +274 -274
  26. package/docs/getting-started/quickstart.md +157 -157
  27. package/docs/improvements/FEATURE_PROPOSALS.md +337 -0
  28. package/docs/improvements/PHASE1_IMPLEMENTATION.md +325 -0
  29. package/docs/improvements/PHASE2_IMPLEMENTATION.md +567 -0
  30. package/docs/improvements/README.md +86 -68
  31. package/docs/improvements/ota-and-status-enhancements.md +911 -0
  32. package/docs/improvements/ota-status-architecture-diagrams.md +658 -0
  33. package/docs/improvements/ota-status-quick-reference.md +284 -0
  34. package/docs/platformio-publishing.md +255 -0
  35. package/docs/platformio-setup-summary.md +121 -0
  36. package/docs/troubleshooting/common-issues.md +520 -520
  37. package/docs/troubleshooting/faq.md +472 -472
  38. package/docs/tutorials/basic-examples.md +717 -717
  39. package/docs/wiki/API-Reference.md +245 -245
  40. package/docs/wiki/Complete-Documentation.md +122 -122
  41. package/examples/alteriom/README.md +139 -81
  42. package/examples/alteriom/alteriom.ino +186 -185
  43. package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
  44. package/examples/alteriom/platformio.ini +24 -24
  45. package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
  46. package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
  47. package/examples/alteriomImproved/platformio.ini +25 -0
  48. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
  49. package/examples/alteriomPhase1/phase1_features.ino +242 -0
  50. package/examples/alteriomPhase1/platformio.ini +25 -0
  51. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
  52. package/examples/alteriomPhase2/phase2_features.ino +186 -0
  53. package/examples/alteriomPhase2/platformio.ini +25 -0
  54. package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
  55. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
  56. package/examples/alteriomSensorNode/platformio.ini +25 -0
  57. package/examples/basic/basic.ino +66 -66
  58. package/examples/basic/platformio.ini +25 -25
  59. package/examples/bridge/bridge.ino +51 -51
  60. package/examples/bridge/mesh_event_publisher.hpp +253 -0
  61. package/examples/bridge/mesh_topology_reporter.hpp +303 -0
  62. package/examples/bridge/mqtt_command_bridge.hpp +459 -0
  63. package/examples/bridge/mqtt_status_bridge.hpp +519 -0
  64. package/examples/bridge/platformio.ini +25 -25
  65. package/examples/echoNode/echoNode.ino +33 -33
  66. package/examples/echoNode/platformio.ini +25 -25
  67. package/examples/logClient/logClient.ino +109 -109
  68. package/examples/logClient/platformio.ini +25 -25
  69. package/examples/logServer/logServer.ino +81 -81
  70. package/examples/logServer/platformio.ini +25 -25
  71. package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
  72. package/examples/meshCommandNode/meshCommandNode.ino +263 -0
  73. package/examples/meshCommandNode/platformio.ini +25 -0
  74. package/examples/mqttBridge/mqttBridge.ino +118 -118
  75. package/examples/mqttBridge/platformio.ini +26 -26
  76. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
  77. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
  78. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
  79. package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
  80. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
  81. package/examples/mqttCommandBridge/platformio.ini +26 -0
  82. package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
  83. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
  84. package/examples/mqttStatusBridge/platformio.ini +26 -0
  85. package/examples/mqttTopologyTest/README.md +467 -0
  86. package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
  87. package/examples/mqttTopologyTest/platformio.ini +26 -0
  88. package/examples/namedMesh/namedMesh.ino +97 -97
  89. package/examples/namedMesh/platformio.ini +25 -25
  90. package/examples/otaReceiver/otaReceiver.ino +79 -79
  91. package/examples/otaReceiver/platformio.ini +25 -25
  92. package/examples/otaSender/otaSender.ino +160 -151
  93. package/examples/otaSender/platformio.ini +25 -25
  94. package/examples/startHere/platformio.ini +25 -25
  95. package/examples/startHere/startHere.ino +159 -159
  96. package/examples/webServer/platformio.ini +27 -27
  97. package/examples/webServer/webServer.ino +89 -89
  98. package/keywords.txt +48 -48
  99. package/library.json +55 -34
  100. package/library.properties +10 -10
  101. package/package.json +86 -78
  102. package/src/AlteriomPainlessMesh.h +97 -97
  103. package/src/arduino/wifi.hpp +365 -365
  104. package/src/boost/asynctcp.hpp +279 -279
  105. package/src/painlessMesh.h +70 -70
  106. package/src/painlessMeshSTA.cpp +236 -236
  107. package/src/painlessMeshSTA.h +58 -58
  108. package/src/painlessTaskOptions.h +4 -4
  109. package/src/painlessmesh/base64.hpp +111 -111
  110. package/src/painlessmesh/buffer.hpp +229 -229
  111. package/src/painlessmesh/callback.hpp +91 -91
  112. package/src/painlessmesh/configuration.hpp +77 -77
  113. package/src/painlessmesh/connection.hpp +192 -192
  114. package/src/painlessmesh/layout.hpp +188 -188
  115. package/src/painlessmesh/logger.hpp +158 -158
  116. package/src/painlessmesh/memory.hpp +119 -119
  117. package/src/painlessmesh/mesh.hpp +761 -560
  118. package/src/painlessmesh/metrics.hpp +322 -322
  119. package/src/painlessmesh/ntp.hpp +263 -263
  120. package/src/painlessmesh/ota.hpp +582 -553
  121. package/src/painlessmesh/plugin.hpp +188 -188
  122. package/src/painlessmesh/protocol.hpp +813 -813
  123. package/src/painlessmesh/router.hpp +322 -322
  124. package/src/painlessmesh/tcp.hpp +71 -71
  125. package/src/painlessmesh/validation.hpp +238 -238
  126. package/src/plugin/performance.hpp +214 -214
  127. package/src/plugin/remote.hpp +64 -64
  128. package/src/scheduler.cpp +10 -10
  129. package/src/wifi.cpp +2 -2
@@ -0,0 +1,224 @@
1
+ #ifndef ALTERIOM_SENSOR_PACKAGE_HPP
2
+ #define ALTERIOM_SENSOR_PACKAGE_HPP
3
+
4
+ #include "painlessmesh/plugin.hpp"
5
+
6
+ namespace alteriom {
7
+
8
+ /**
9
+ * @brief Sensor data package for broadcasting environmental measurements
10
+ *
11
+ * This package is designed for Alteriom's IoT sensor network requirements,
12
+ * allowing nodes to share environmental data across the mesh.
13
+ */
14
+ class SensorPackage : public painlessmesh::plugin::BroadcastPackage {
15
+ public:
16
+ double temperature = 0.0; // Temperature in Celsius
17
+ double humidity = 0.0; // Relative humidity percentage
18
+ double pressure = 0.0; // Atmospheric pressure in hPa
19
+ uint32_t sensorId = 0; // Unique sensor identifier
20
+ uint32_t timestamp = 0; // Unix timestamp of measurement
21
+ uint8_t batteryLevel = 0; // Battery level percentage
22
+
23
+ SensorPackage()
24
+ : BroadcastPackage(200) {} // Type ID 200 for Alteriom sensors
25
+
26
+ SensorPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
27
+ temperature = jsonObj["temp"];
28
+ humidity = jsonObj["hum"];
29
+ pressure = jsonObj["press"];
30
+ sensorId = jsonObj["sid"];
31
+ timestamp = jsonObj["ts"];
32
+ batteryLevel = jsonObj["bat"];
33
+ }
34
+
35
+ JsonObject addTo(JsonObject&& jsonObj) const {
36
+ jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
37
+ jsonObj["temp"] = temperature;
38
+ jsonObj["hum"] = humidity;
39
+ jsonObj["press"] = pressure;
40
+ jsonObj["sid"] = sensorId;
41
+ jsonObj["ts"] = timestamp;
42
+ jsonObj["bat"] = batteryLevel;
43
+ return jsonObj;
44
+ }
45
+
46
+ #if ARDUINOJSON_VERSION_MAJOR < 7
47
+ size_t jsonObjectSize() const { return JSON_OBJECT_SIZE(noJsonFields + 6); }
48
+ #endif
49
+ };
50
+
51
+ /**
52
+ * @brief Command package for controlling Alteriom devices
53
+ *
54
+ * Single-destination package for sending specific commands to individual nodes.
55
+ */
56
+ class CommandPackage : public painlessmesh::plugin::SinglePackage {
57
+ public:
58
+ uint8_t command = 0; // Command type
59
+ uint32_t targetDevice = 0; // Target device ID
60
+ TSTRING parameters = ""; // Command parameters as JSON string
61
+ uint32_t commandId = 0; // Unique command identifier for tracking
62
+
63
+ CommandPackage() : SinglePackage(201) {} // Type ID 201 for Alteriom commands
64
+
65
+ CommandPackage(JsonObject jsonObj) : SinglePackage(jsonObj) {
66
+ command = jsonObj["cmd"];
67
+ targetDevice = jsonObj["target"];
68
+ parameters = jsonObj["params"].as<TSTRING>();
69
+ commandId = jsonObj["cid"];
70
+ }
71
+
72
+ JsonObject addTo(JsonObject&& jsonObj) const {
73
+ jsonObj = SinglePackage::addTo(std::move(jsonObj));
74
+ jsonObj["cmd"] = command;
75
+ jsonObj["target"] = targetDevice;
76
+ jsonObj["params"] = parameters;
77
+ jsonObj["cid"] = commandId;
78
+ return jsonObj;
79
+ }
80
+
81
+ #if ARDUINOJSON_VERSION_MAJOR < 7
82
+ size_t jsonObjectSize() const {
83
+ return JSON_OBJECT_SIZE(noJsonFields + 4) + parameters.length();
84
+ }
85
+ #endif
86
+ };
87
+
88
+ /**
89
+ * @brief Status report package for device health monitoring
90
+ */
91
+ class StatusPackage : public painlessmesh::plugin::BroadcastPackage {
92
+ public:
93
+ uint8_t deviceStatus = 0; // Device status flags
94
+ uint32_t uptime = 0; // Device uptime in seconds
95
+ uint16_t freeMemory = 0; // Free memory in KB
96
+ uint8_t wifiStrength = 0; // WiFi signal strength
97
+ TSTRING firmwareVersion = ""; // Current firmware version
98
+
99
+ StatusPackage() : BroadcastPackage(202) {} // Type ID 202 for Alteriom status
100
+
101
+ StatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
102
+ deviceStatus = jsonObj["status"];
103
+ uptime = jsonObj["uptime"];
104
+ freeMemory = jsonObj["mem"];
105
+ wifiStrength = jsonObj["wifi"];
106
+ firmwareVersion = jsonObj["fw"].as<TSTRING>();
107
+ }
108
+
109
+ JsonObject addTo(JsonObject&& jsonObj) const {
110
+ jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
111
+ jsonObj["status"] = deviceStatus;
112
+ jsonObj["uptime"] = uptime;
113
+ jsonObj["mem"] = freeMemory;
114
+ jsonObj["wifi"] = wifiStrength;
115
+ jsonObj["fw"] = firmwareVersion;
116
+ return jsonObj;
117
+ }
118
+
119
+ #if ARDUINOJSON_VERSION_MAJOR < 7
120
+ size_t jsonObjectSize() const {
121
+ return JSON_OBJECT_SIZE(noJsonFields + 5) + firmwareVersion.length();
122
+ }
123
+ #endif
124
+ };
125
+
126
+ /**
127
+ * @brief Enhanced status package with comprehensive health metrics (Phase 1)
128
+ *
129
+ * This is an extended version of StatusPackage that includes additional
130
+ * mesh statistics, performance metrics, and alerting capabilities.
131
+ * Type ID 203 is used to distinguish from the basic StatusPackage (202).
132
+ */
133
+ class EnhancedStatusPackage : public painlessmesh::plugin::BroadcastPackage {
134
+ public:
135
+ // Device Health (from original StatusPackage)
136
+ uint8_t deviceStatus = 0; // Device status flags
137
+ uint32_t uptime = 0; // Device uptime in seconds
138
+ uint16_t freeMemory = 0; // Free memory in KB
139
+ uint8_t wifiStrength = 0; // WiFi signal strength
140
+ TSTRING firmwareVersion = ""; // Current firmware version
141
+ TSTRING firmwareMD5 = ""; // Firmware hash for OTA verification
142
+
143
+ // Mesh Statistics
144
+ uint16_t nodeCount = 0; // Number of known nodes in mesh
145
+ uint8_t connectionCount = 0; // Number of direct connections
146
+ uint32_t messagesReceived = 0; // Total messages received
147
+ uint32_t messagesSent = 0; // Total messages sent
148
+ uint32_t messagesDropped = 0; // Total messages dropped/failed
149
+
150
+ // Performance Metrics
151
+ uint16_t avgLatency = 0; // Average message latency in ms
152
+ uint8_t packetLossRate = 0; // Packet loss rate percentage (0-100)
153
+ uint16_t throughput = 0; // Network throughput in bytes/sec
154
+
155
+ // Warnings/Alerts
156
+ uint8_t alertFlags = 0; // Bit flags for various alert conditions
157
+ TSTRING lastError = ""; // Last error message for diagnostics
158
+
159
+ EnhancedStatusPackage()
160
+ : BroadcastPackage(203) {} // Type ID 203 for enhanced status
161
+
162
+ EnhancedStatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
163
+ deviceStatus = jsonObj["status"];
164
+ uptime = jsonObj["uptime"];
165
+ freeMemory = jsonObj["mem"];
166
+ wifiStrength = jsonObj["wifi"];
167
+ firmwareVersion = jsonObj["fw"].as<TSTRING>();
168
+ firmwareMD5 = jsonObj["fwMD5"].as<TSTRING>();
169
+
170
+ nodeCount = jsonObj["nodes"];
171
+ connectionCount = jsonObj["conns"];
172
+ messagesReceived = jsonObj["msgRx"];
173
+ messagesSent = jsonObj["msgTx"];
174
+ messagesDropped = jsonObj["msgDrop"];
175
+
176
+ avgLatency = jsonObj["latency"];
177
+ packetLossRate = jsonObj["loss"];
178
+ throughput = jsonObj["throughput"];
179
+
180
+ alertFlags = jsonObj["alerts"];
181
+ lastError = jsonObj["lastErr"].as<TSTRING>();
182
+ }
183
+
184
+ JsonObject addTo(JsonObject&& jsonObj) const {
185
+ jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
186
+
187
+ // Device Health
188
+ jsonObj["status"] = deviceStatus;
189
+ jsonObj["uptime"] = uptime;
190
+ jsonObj["mem"] = freeMemory;
191
+ jsonObj["wifi"] = wifiStrength;
192
+ jsonObj["fw"] = firmwareVersion;
193
+ jsonObj["fwMD5"] = firmwareMD5;
194
+
195
+ // Mesh Statistics
196
+ jsonObj["nodes"] = nodeCount;
197
+ jsonObj["conns"] = connectionCount;
198
+ jsonObj["msgRx"] = messagesReceived;
199
+ jsonObj["msgTx"] = messagesSent;
200
+ jsonObj["msgDrop"] = messagesDropped;
201
+
202
+ // Performance Metrics
203
+ jsonObj["latency"] = avgLatency;
204
+ jsonObj["loss"] = packetLossRate;
205
+ jsonObj["throughput"] = throughput;
206
+
207
+ // Alerts
208
+ jsonObj["alerts"] = alertFlags;
209
+ jsonObj["lastErr"] = lastError;
210
+
211
+ return jsonObj;
212
+ }
213
+
214
+ #if ARDUINOJSON_VERSION_MAJOR < 7
215
+ size_t jsonObjectSize() const {
216
+ return JSON_OBJECT_SIZE(noJsonFields + 18) + firmwareVersion.length() +
217
+ firmwareMD5.length() + lastError.length();
218
+ }
219
+ #endif
220
+ };
221
+
222
+ } // namespace alteriom
223
+
224
+ #endif // ALTERIOM_SENSOR_PACKAGE_HPP
@@ -0,0 +1,186 @@
1
+ //************************************************************
2
+ // Phase 2 Features Example
3
+ //
4
+ // This example demonstrates the two major Phase 2 features:
5
+ // 1. Broadcast OTA (Option 1A) - True mesh-wide firmware distribution
6
+ // 2. MQTT Status Bridge (Option 2E) - Professional monitoring
7
+ //
8
+ // Phase 2 builds on Phase 1's foundation:
9
+ // - Phase 1: Compressed OTA + Enhanced Status
10
+ // - Phase 2: Broadcast OTA + MQTT Status Bridge
11
+ //
12
+ // Broadcast OTA Benefits:
13
+ // - Dramatically reduces network traffic (1 broadcast vs N unicasts)
14
+ // - Faster distribution to large meshes (parallel vs sequential)
15
+ // - Scales to 50+ nodes efficiently
16
+ // - Backward compatible with Phase 1
17
+ //
18
+ // MQTT Status Bridge Benefits:
19
+ // - Professional monitoring tools (Grafana, InfluxDB, Prometheus)
20
+ // - Cloud integration via MQTT
21
+ // - Real-time mesh visibility
22
+ // - Automated alerting
23
+ //************************************************************
24
+
25
+ #include "painlessMesh.h"
26
+
27
+ // Mesh configuration
28
+ #define MESH_PREFIX "AlteriomMesh"
29
+ #define MESH_PASSWORD "meshPassword123"
30
+ #define MESH_PORT 5555
31
+
32
+ // OTA configuration
33
+ #define OTA_PART_SIZE 1024 // Chunk size for OTA transfers
34
+
35
+ Scheduler userScheduler;
36
+ painlessMesh mesh;
37
+
38
+ // Prototypes
39
+ void sendBroadcastOTA();
40
+ void receivedCallback(uint32_t from, String& msg);
41
+ void newConnectionCallback(uint32_t nodeId);
42
+ void changedConnectionCallback();
43
+
44
+ void setup() {
45
+ Serial.begin(115200);
46
+ Serial.println("\n\n=== Phase 2 Features Demo ===\n");
47
+
48
+ mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
49
+ mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
50
+ mesh.onReceive(&receivedCallback);
51
+ mesh.onNewConnection(&newConnectionCallback);
52
+ mesh.onChangedConnections(&changedConnectionCallback);
53
+
54
+ Serial.println("Mesh initialized");
55
+ Serial.println("Phase 2 features:");
56
+ Serial.println(" 1. Broadcast OTA - scales to 50+ nodes");
57
+ Serial.println(" 2. MQTT Status Bridge - professional monitoring");
58
+ Serial.println();
59
+ }
60
+
61
+ void loop() {
62
+ mesh.update();
63
+ }
64
+
65
+ /**
66
+ * Phase 2 Feature 1: Broadcast OTA
67
+ *
68
+ * True mesh-wide broadcast distribution where firmware chunks
69
+ * are broadcast to all nodes simultaneously, dramatically reducing
70
+ * network traffic and improving update speed.
71
+ *
72
+ * Key differences from Phase 1:
73
+ * - Phase 1: Each node requests chunks individually (N unicasts)
74
+ * - Phase 2: Root broadcasts chunks once to all nodes (1 broadcast)
75
+ *
76
+ * Memory impact: +2-5KB per node for chunk tracking
77
+ */
78
+ void sendBroadcastOTA() {
79
+ #ifdef PAINLESSMESH_ENABLE_OTA
80
+
81
+ Serial.println("\n=== Phase 2: Broadcast OTA ===");
82
+
83
+ // Example firmware info
84
+ String firmwareMD5 = "phase2_broadcast_example_md5";
85
+ size_t numParts = 150; // Number of firmware chunks
86
+
87
+ // Phase 2: Enable both compression (Phase 1) AND broadcast (Phase 2)
88
+ // This is the most efficient combination for large meshes
89
+ auto otaTask = mesh.offerOTA(
90
+ "sensor", // Role this firmware is for
91
+ "ESP32", // Hardware type (ESP32 or ESP8266)
92
+ firmwareMD5, // MD5 hash of firmware
93
+ numParts, // Number of data chunks
94
+ false, // Not forced (only update if different MD5)
95
+ true, // *** BROADCAST MODE (Phase 2 feature) ***
96
+ true // Compressed (Phase 1 feature for additional savings)
97
+ );
98
+
99
+ Serial.println("Broadcast OTA announced!");
100
+ Serial.println();
101
+ Serial.println("Phase 2 Broadcast Mode:");
102
+ Serial.println(" - Root node broadcasts each chunk ONCE");
103
+ Serial.println(" - All nodes receive chunks simultaneously");
104
+ Serial.println(" - Dramatically reduced network traffic");
105
+ Serial.println(" - Scales efficiently to 50+ nodes");
106
+ Serial.println();
107
+ Serial.println("Combined with Phase 1 Compression:");
108
+ Serial.println(" - 40-60% bandwidth reduction per chunk");
109
+ Serial.println(" - Faster distribution across large meshes");
110
+ Serial.println(" - Lower energy consumption");
111
+ Serial.println();
112
+ Serial.println("Expected performance for 50-node mesh:");
113
+ Serial.println(" - Without broadcast: 50 unicast transmissions per chunk");
114
+ Serial.println(" - With broadcast: 1 broadcast per chunk");
115
+ Serial.println(" - Network load reduction: ~98%");
116
+ Serial.println();
117
+ Serial.println("Architecture:");
118
+ Serial.println(" Root Node:");
119
+ Serial.println(" ├─> Broadcast: Announce(firmware_info)");
120
+ Serial.println(" ├─> Broadcast: Data(chunk_0)");
121
+ Serial.println(" ├─> Broadcast: Data(chunk_1)");
122
+ Serial.println(" └─> ... continues for all chunks");
123
+ Serial.println(" ");
124
+ Serial.println(" All Nodes:");
125
+ Serial.println(" ├─> Listen for broadcast announcements");
126
+ Serial.println(" ├─> Receive and cache chunks as they arrive");
127
+ Serial.println(" ├─> Assemble firmware from cached chunks");
128
+ Serial.println(" └─> Reboot into new firmware when complete");
129
+
130
+ #else
131
+ Serial.println("OTA not enabled. Define PAINLESSMESH_ENABLE_OTA");
132
+ #endif
133
+ }
134
+
135
+ /**
136
+ * Callback when messages are received
137
+ */
138
+ void receivedCallback(uint32_t from, String& msg) {
139
+ Serial.printf("Received from %u: %s\n", from, msg.c_str());
140
+ }
141
+
142
+ void newConnectionCallback(uint32_t nodeId) {
143
+ Serial.printf("New connection: %u\n", nodeId);
144
+ Serial.printf("Total nodes in mesh: %d\n", mesh.getNodeList().size() + 1);
145
+ }
146
+
147
+ void changedConnectionCallback() {
148
+ Serial.println("Connections changed");
149
+ Serial.printf("Total nodes: %d\n", mesh.getNodeList().size() + 1);
150
+ }
151
+
152
+ /**
153
+ * Phase 2 Benefits Summary:
154
+ *
155
+ * 1. Broadcast OTA (Option 1A):
156
+ * - Scales to 50-100 node meshes
157
+ * - ~98% reduction in network traffic vs unicast
158
+ * - Parallel distribution to all nodes
159
+ * - Maintains backward compatibility
160
+ * - Memory overhead: +2-5KB per node
161
+ *
162
+ * 2. MQTT Status Bridge (Option 2E):
163
+ * - Professional monitoring tools integration
164
+ * - Real-time mesh visibility via MQTT topics
165
+ * - Grafana/InfluxDB dashboards
166
+ * - Prometheus metrics collection
167
+ * - Home Assistant automation
168
+ * - Cloud-ready architecture
169
+ * - Configurable publish intervals
170
+ * - Multiple topic streams (nodes, topology, metrics, alerts)
171
+ *
172
+ * When to use Phase 2:
173
+ * - Meshes with 10+ nodes (broadcast efficiency kicks in)
174
+ * - Production deployments requiring monitoring
175
+ * - Systems needing cloud integration
176
+ * - Enterprise environments with existing monitoring tools
177
+ * - Large-scale deployments (50+ nodes)
178
+ *
179
+ * Migration from Phase 1:
180
+ * - Broadcast OTA: Just set broadcasted=true in offerOTA()
181
+ * - MQTT Bridge: Include mqtt_status_bridge.hpp and configure
182
+ * - Both features are fully backward compatible
183
+ * - Can be deployed incrementally
184
+ *
185
+ * Next: Phase 3 features (progressive rollout + telemetry streams)
186
+ */
@@ -0,0 +1,25 @@
1
+ [platformio]
2
+ src_dir = .
3
+
4
+ [env]
5
+ lib_deps =
6
+ bblanchon/ArduinoJson
7
+ arkhipenko/TaskScheduler
8
+
9
+ [env:esp8266]
10
+ platform = espressif8266
11
+ board = nodemcuv2
12
+ framework = arduino
13
+ lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
14
+ lib_deps =
15
+ ${env.lib_deps} ; Inherit common dependencies
16
+ esp32async/ESPAsyncTCP ; Only for ESP8266
17
+
18
+ [env:esp32]
19
+ platform = espressif32
20
+ board = esp32dev
21
+ framework = arduino
22
+ lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
23
+ lib_deps =
24
+ ${env.lib_deps} ; Inherit common dependencies
25
+ esp32async/AsyncTCP