@alteriom/painlessmesh 1.10.0 → 2.0.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.
- package/BRIDGE_TO_INTERNET.md +167 -29
- package/CHANGELOG.md +483 -0
- package/CONTRIBUTING.md +56 -53
- package/README.md +100 -95
- package/RELEASE_GUIDE.md +81 -780
- package/examples/alteriom/README.md +8 -10
- package/examples/alteriom/alteriom.ino +2 -2
- package/examples/alteriom/alteriom_sensor_package.hpp +17 -11
- package/examples/alteriom/mppt_example/alteriom_custom_package_template.hpp +320 -0
- package/examples/alteriom/mppt_example/alteriom_sensor_package.hpp +1389 -0
- package/examples/alteriom/mppt_example/{alteriom_mppt_example.ino → mppt_example.ino} +4 -0
- package/examples/basic/test/simulator/README.md +3 -3
- package/examples/bridge_failover/README.md +51 -14
- package/examples/commandControl/commandControl.ino +86 -0
- package/examples/commandControl/platformio.ini +26 -0
- package/examples/mqttBridge/mqttBridge.ino +4 -0
- package/examples/mqttBridge/platformio.ini +1 -1
- package/examples/otaSender/otaSender.ino +5 -1
- package/examples/priority/README.md +1 -1
- package/examples/priority/{priority_basic_example.ino → priority_basic_example/priority_basic_example.ino} +4 -4
- package/examples/priority/{priority_with_queue.ino → priority_with_queue/priority_with_queue.ino} +20 -2
- package/examples/reliableSensorLogging/platformio.ini +26 -0
- package/examples/reliableSensorLogging/reliableSensorLogging.ino +151 -0
- package/examples/sendToInternet/README.md +12 -5
- package/examples/sendToInternet/{CMakeLists.txt → pc_node/CMakeLists.txt} +7 -7
- package/examples/sendToInternet/{PC_NODE_README.md → pc_node/PC_NODE_README.md} +15 -15
- package/examples/sendToInternet/{build.sh → pc_node/build.sh} +5 -5
- package/examples/sendToInternet/{pc_mesh_node.cpp → pc_node/pc_mesh_node.cpp} +12 -1
- package/examples/sharedGateway/README.md +1 -2
- package/keywords.txt +50 -1
- package/library.json +8 -6
- package/library.properties +2 -2
- package/package.json +3 -3
- package/src/AlteriomPainlessMesh.h +3 -3
- package/src/arduino/wifi.hpp +556 -126
- package/src/painlessMesh.h +2 -2
- package/src/painlessMeshSTA.cpp +607 -87
- package/src/painlessMeshSTA.h +135 -3
- package/src/painlessmesh/ack.hpp +283 -0
- package/src/painlessmesh/buffer.hpp +70 -8
- package/src/painlessmesh/callback.hpp +38 -5
- package/src/painlessmesh/configuration.hpp +69 -1
- package/src/painlessmesh/connection.hpp +12 -5
- package/src/painlessmesh/gateway.hpp +270 -5
- package/src/painlessmesh/layout.hpp +70 -2
- package/src/painlessmesh/logger.hpp +15 -0
- package/src/painlessmesh/mesh.hpp +552 -48
- package/src/painlessmesh/ntp.hpp +2 -4
- package/src/painlessmesh/plugin.hpp +30 -6
- package/src/painlessmesh/protocol.hpp +55 -2
- package/src/painlessmesh/router.hpp +192 -77
- package/src/painlessmesh/tcp.hpp +10 -0
- package/src/painlessmesh/message_tracker.hpp +0 -311
- /package/examples/sendToInternet/{mock_server_test.ino → mock_server_test/mock_server_test.ino} +0 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
6
6
|
|
|
7
|
-
**Version
|
|
7
|
+
**Version 2.0.0** — delivery confirmation, a unified send path, and gateway failover, routing and channel following validated on a six-family hardware rig
|
|
8
8
|
|
|
9
9
|
[](https://github.com/Alteriom/painlessMesh/actions/workflows/ci.yml)
|
|
10
10
|
[](https://github.com/Alteriom/painlessMesh/actions/workflows/docs.yml)
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
[](https://github.com/Alteriom/painlessMesh/releases)
|
|
13
13
|
[](https://www.npmjs.com/package/@alteriom/painlessmesh)
|
|
14
14
|
[](https://registry.platformio.org/libraries/alteriom/AlteriomPainlessMesh)
|
|
15
|
-
[](https://www.arduino.cc/reference/en/libraries/alteriompainlessmesh/)
|
|
16
15
|
|
|
17
16
|
</div>
|
|
18
17
|
|
|
@@ -156,12 +155,13 @@ See [BRIDGE_TO_INTERNET.md](BRIDGE_TO_INTERNET.md) for complete documentation.
|
|
|
156
155
|
|
|
157
156
|
**High Availability for Critical Systems**
|
|
158
157
|
|
|
159
|
-
- 🎯 **RSSI-Based Election** - Best signal
|
|
160
|
-
-
|
|
161
|
-
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
158
|
+
- 🎯 **RSSI-Based Election** - Best router signal wins the bridge role; ties go to uptime, then free memory, then node ID
|
|
159
|
+
- 📣 **A bridge that stops cleanly says so** - `mesh.stop()` on a bridge announces it is leaving, and the candidates hold their election within seconds
|
|
160
|
+
- 🔍 **Heartbeat Detection** - A bridge that loses power is noticed when its last status ages out: the bridge timeout (60 s) plus up to one 30 s monitor tick
|
|
161
|
+
- 🏠 **The mesh follows the bridge** - Peers learn the elected bridge's channel from the takeover message and treat it as home; a node that loses its uplink there rescans that channel first
|
|
162
|
+
- 🌐 **Distributed Consensus** - No single coordinator; every node evaluates the same candidates by the same rules
|
|
163
|
+
- 🛡️ **Split-Brain Prevention** - One election at a time, a 60 s hold between role changes, and a minimum router RSSI for a lone candidate
|
|
164
|
+
- 🔬 **Validated on hardware** - The failover scenario runs on the Alteriom rig with a real router; see [CHANGELOG.md](CHANGELOG.md)
|
|
165
165
|
|
|
166
166
|
**Use Cases:**
|
|
167
167
|
- Fish farm alarm systems requiring 24/7 Internet connectivity
|
|
@@ -184,7 +184,7 @@ void bridgeRoleCallback(bool isBridge, const String& reason) {
|
|
|
184
184
|
|
|
185
185
|
See [bridge_failover example](examples/bridge_failover/) for complete documentation.
|
|
186
186
|
|
|
187
|
-
#### 🌉 Multi-Bridge Coordination
|
|
187
|
+
#### 🌉 Multi-Bridge Coordination
|
|
188
188
|
|
|
189
189
|
**Enterprise Load Balancing and Geographic Redundancy**
|
|
190
190
|
|
|
@@ -232,7 +232,7 @@ mesh.onBridgeCoordinationChanged(
|
|
|
232
232
|
|
|
233
233
|
See [BRIDGE_TO_INTERNET.md](BRIDGE_TO_INTERNET.md) for multi-bridge documentation.
|
|
234
234
|
|
|
235
|
-
#### 📬 Message Queue for Offline Mode
|
|
235
|
+
#### 📬 Message Queue for Offline Mode
|
|
236
236
|
|
|
237
237
|
**Zero Data Loss During Internet Outages**
|
|
238
238
|
|
|
@@ -255,14 +255,15 @@ See [BRIDGE_TO_INTERNET.md](BRIDGE_TO_INTERNET.md) for multi-bridge documentatio
|
|
|
255
255
|
// Enable message queue with max 100 messages
|
|
256
256
|
mesh.enableMessageQueue(true, 100);
|
|
257
257
|
|
|
258
|
-
// Queue critical alarm
|
|
258
|
+
// Queue a critical alarm for the Internet endpoint; it is sent when a
|
|
259
|
+
// gateway with Internet is available and never evicted by lower priorities
|
|
259
260
|
String criticalAlarm = "{\"sensor\":\"O2\",\"value\":2.5,\"alarm\":true}";
|
|
260
|
-
mesh.queueMessage(
|
|
261
|
+
mesh.queueMessage(criticalAlarm, "https://api.example.com/alarm", PRIORITY_CRITICAL);
|
|
261
262
|
```
|
|
262
263
|
|
|
263
264
|
See [BRIDGE_TO_INTERNET.md](BRIDGE_TO_INTERNET.md) for message queue documentation.
|
|
264
265
|
|
|
265
|
-
#### 🌐 Shared Gateway Mode
|
|
266
|
+
#### 🌐 Shared Gateway Mode
|
|
266
267
|
|
|
267
268
|
**All Nodes as Internet Gateways with Automatic Failover**
|
|
268
269
|
|
|
@@ -298,8 +299,8 @@ mesh.sendToInternet(
|
|
|
298
299
|
);
|
|
299
300
|
|
|
300
301
|
// Monitor gateway changes
|
|
301
|
-
mesh.onGatewayChanged([](uint32_t newGateway) {
|
|
302
|
-
Serial.printf("Primary gateway: %u\n", newGateway);
|
|
302
|
+
mesh.onGatewayChanged([](uint32_t oldGateway, uint32_t newGateway) {
|
|
303
|
+
Serial.printf("Primary gateway: %u -> %u\n", oldGateway, newGateway);
|
|
303
304
|
});
|
|
304
305
|
```
|
|
305
306
|
|
|
@@ -331,6 +332,32 @@ The library handles routing and network management automatically, so you can foc
|
|
|
331
332
|
|
|
332
333
|
painlessMesh is a true ad-hoc network, meaning that no-planning, central controller, or router is required. Any system of 1 or more nodes will self-organize into fully functional mesh. The maximum size of the mesh is limited (we think) by the amount of memory in the heap that can be allocated to the sub-connections buffer and so should be really quite high.
|
|
333
334
|
|
|
335
|
+
### ESP8266 capacity
|
|
336
|
+
|
|
337
|
+
The ESP8266 is specified for **small meshes**, or as a **leaf** in larger ones.
|
|
338
|
+
Measured as an interior node of a seven-node mesh it runs at 10–13 KB free —
|
|
339
|
+
a working set that tracks its live connections and the traffic through them,
|
|
340
|
+
not a leak — and at that level a single 8 KB package or one OTA part can fail
|
|
341
|
+
to allocate. That is the part's limit, not a library defect. Every ESP32
|
|
342
|
+
family holds within a few percent of its starting heap in the same mesh.
|
|
343
|
+
|
|
344
|
+
Configure an ESP8266 as a leaf with `init(..., maxconn = 0)` (or `1` to allow
|
|
345
|
+
one child). The library checks every thirty seconds on ESP8266 and logs an
|
|
346
|
+
`ERROR` when the node is below 12 KB free with more than one child attached;
|
|
347
|
+
`mesh.overCapacity()` reports the same condition to the sketch, and
|
|
348
|
+
`mesh.apChildren()` says how many are attached.
|
|
349
|
+
|
|
350
|
+
### Validated on hardware
|
|
351
|
+
|
|
352
|
+
Every 2.0 change to failover, routing, channel following and the station
|
|
353
|
+
scan was found in the serial logs of the Alteriom hardware-in-the-loop rig —
|
|
354
|
+
an ESP32, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-S3 and ESP8266 in one mesh with
|
|
355
|
+
a real router — and confirmed there. The release gate is three consecutive
|
|
356
|
+
clean runs of the rig's whole suite (mesh formation, delivery and
|
|
357
|
+
acknowledgement, priorities, dedicated and shared gateways, Internet relay,
|
|
358
|
+
gateway failover, mesh OTA, sustained soak). Each fix in the changelog names
|
|
359
|
+
the run that found it.
|
|
360
|
+
|
|
334
361
|
### JSON based
|
|
335
362
|
|
|
336
363
|
painlessMesh uses JSON objects for all its messaging. There are a couple of reasons for this. First, it makes the code and the messages human readable and painless to understand and second, it makes it painless to integrate painlessMesh with javascript front-ends, web applications, and other apps. Some performance is lost, but I haven’t been running into performance issues yet. Converting to binary messaging would be fairly straight forward if someone wants to contribute.
|
|
@@ -341,29 +368,29 @@ painlessMesh is designed to be used with Arduino, but it does not use the Arduin
|
|
|
341
368
|
|
|
342
369
|
### painlessMesh is not IP networking
|
|
343
370
|
|
|
344
|
-
painlessMesh does not create a TCP/IP network of nodes. Rather each of the nodes is uniquely identified by its 32bit chipId which is retrieved from the esp8266/esp32 using the `system_get_chip_id()` call in the SDK. Every node will have a unique number. Messages can either be broadcast to all the nodes on the mesh, or sent specifically to an individual node which is identified by its `nodeId
|
|
371
|
+
painlessMesh does not create a TCP/IP network of nodes. Rather each of the nodes is uniquely identified by its 32bit chipId which is retrieved from the esp8266/esp32 using the `system_get_chip_id()` call in the SDK. Every node will have a unique number. Messages can either be broadcast to all the nodes on the mesh, or sent specifically to an individual node which is identified by its `nodeId`.
|
|
345
372
|
|
|
346
373
|
### Limitations and caveats
|
|
347
374
|
|
|
348
375
|
- Try to avoid using `delay()` in your code. To maintain the mesh we need to perform some tasks in the background. Using `delay()` will stop these tasks from happening and can cause the mesh to lose stability/fall apart. Instead, we recommend using [TaskScheduler](http://playground.arduino.cc/Code/TaskScheduler) which is used in `painlessMesh` itself. Documentation can be found [here](https://github.com/arkhipenko/TaskScheduler/wiki/Full-Document). For other examples on how to use the scheduler see the example folder.
|
|
349
376
|
- `painlessMesh` subscribes to WiFi events. Please be aware that as a result `painlessMesh` can be incompatible with user programs/other libraries that try to bind to the same events.
|
|
350
377
|
- Try to be conservative in the number of messages (and especially broadcast messages) you sent per minute. This is to prevent the hardware from overloading. Both esp8266 and esp32 are limited in processing power/memory, making it easy to overload the mesh and destabilize it. And while `painlessMesh` tries to prevent this from happening, it is not always possible to do so.
|
|
351
|
-
- Messages can go missing or be dropped due to high traffic and you can not rely on all messages to be delivered. One suggestion to work around is to resend messages every so often. Even if some go missing, most should go through. Another option is to have your nodes send replies when they receive a message. The sending nodes can
|
|
378
|
+
- Messages can go missing or be dropped due to high traffic and you can not rely on all messages to be delivered. One suggestion to work around is to resend messages every so often. Even if some go missing, most should go through. Another option is to have your nodes send replies when they receive a message. The sending nodes can then resend the message if they haven’t gotten a reply in a certain amount of time.
|
|
352
379
|
|
|
353
380
|
## Installation
|
|
354
381
|
|
|
355
382
|
### Arduino Library Manager
|
|
356
383
|
|
|
357
|
-
|
|
384
|
+
The library is in the Arduino Library Manager as **Alteriom PainlessMesh**:
|
|
358
385
|
|
|
359
386
|
1. Open Arduino IDE
|
|
360
387
|
2. Go to **Tools** → **Manage Libraries...**
|
|
361
|
-
3. Search for **"
|
|
362
|
-
4.
|
|
388
|
+
3. Search for **"Alteriom PainlessMesh"** and click **Install**; accept the dependencies it offers (ArduinoJson, TaskScheduler, PubSubClient)
|
|
389
|
+
4. Also install **AsyncTCP** (ESP32) or **ESPAsyncTCP** (ESP8266) from the same dialog; the Library Manager cannot pick one per platform, so they are not listed as dependencies
|
|
363
390
|
|
|
364
|
-
The
|
|
391
|
+
The index follows a GitHub release within a day. The header `AlteriomPainlessMesh.h` gives access to the core painlessMesh functionality and the Alteriom extensions; `painlessMesh.h` alone gives the core.
|
|
365
392
|
|
|
366
|
-
#### Manual Installation
|
|
393
|
+
#### Manual Installation
|
|
367
394
|
|
|
368
395
|
**Option 1: Download ZIP from GitHub Release**
|
|
369
396
|
|
|
@@ -383,7 +410,12 @@ git clone https://github.com/Alteriom/painlessMesh.git AlteriomPainlessMesh
|
|
|
383
410
|
|
|
384
411
|
### PlatformIO
|
|
385
412
|
|
|
386
|
-
|
|
413
|
+
The library is published on the [PlatformIO registry](https://registry.platformio.org/libraries/alteriom/AlteriomPainlessMesh) as `alteriom/AlteriomPainlessMesh`:
|
|
414
|
+
|
|
415
|
+
```ini
|
|
416
|
+
lib_deps =
|
|
417
|
+
alteriom/AlteriomPainlessMesh@^2.0.0
|
|
418
|
+
```
|
|
387
419
|
|
|
388
420
|
### Dependencies
|
|
389
421
|
|
|
@@ -392,7 +424,7 @@ painlessMesh makes use of the following libraries, which can be installed throug
|
|
|
392
424
|
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson)
|
|
393
425
|
- [TaskScheduler](https://github.com/arkhipenko/TaskScheduler)
|
|
394
426
|
- [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) (ESP8266)
|
|
395
|
-
- [AsyncTCP](https://github.com/ESP32Async/AsyncTCP) (ESP32) - v3.3.0
|
|
427
|
+
- [AsyncTCP](https://github.com/ESP32Async/AsyncTCP) (ESP32) - v3.4.7 or later (v3.3.0 was the first to work on the ESP32-C6)
|
|
396
428
|
|
|
397
429
|
If platformio is used to install the library, then the dependencies will be installed automatically.
|
|
398
430
|
|
|
@@ -502,9 +534,13 @@ These types are used internally by painlessMesh for mesh management and are hand
|
|
|
502
534
|
| 4 | `TIME_SYNC` | Time synchronization protocol messages |
|
|
503
535
|
| 5 | `NODE_SYNC_REQUEST` | Node discovery and topology requests |
|
|
504
536
|
| 6 | `NODE_SYNC_REPLY` | Node discovery and topology responses |
|
|
505
|
-
| 7 | `CONTROL` | Deprecated
|
|
506
|
-
| 8 | `BROADCAST` |
|
|
507
|
-
| 9 | `SINGLE` |
|
|
537
|
+
| 7 | `CONTROL` | Deprecated, unused |
|
|
538
|
+
| 8 | `BROADCAST` | Application data for every node |
|
|
539
|
+
| 9 | `SINGLE` | Application data for one node |
|
|
540
|
+
| 620 | `GATEWAY_DATA` | An Internet request routed to a gateway (`sendToInternet()`) |
|
|
541
|
+
| 621 | `GATEWAY_ACK` | The gateway's answer to it |
|
|
542
|
+
| 622 | `GATEWAY_HEARTBEAT` | Gateway health monitoring |
|
|
543
|
+
| 630 | `MESSAGE_ACK` | Delivery confirmation for a message sent with a callback (2.0) |
|
|
508
544
|
|
|
509
545
|
**Note**: These protocol types are managed automatically by painlessMesh and are not typically used in application code.
|
|
510
546
|
|
|
@@ -516,19 +552,19 @@ These are the message types used by applications built on painlessMesh:
|
|
|
516
552
|
|------|-------|---------|--------|
|
|
517
553
|
| 200 | `SensorPackage` | Environmental data | `temperature`, `humidity`, `pressure`, `sensorId`, `timestamp`, `batteryLevel` |
|
|
518
554
|
| 202 | `StatusPackage` | Health monitoring | `deviceStatus`, `uptime`, `freeMemory`, `wifiStrength`, `firmwareVersion` |
|
|
519
|
-
| 204 | `MetricsPackage` | Sensor metrics (
|
|
520
|
-
| 400 | `CommandPackage` | Device control
|
|
521
|
-
| 600 | `MeshNodeListPackage` | Mesh node list (
|
|
522
|
-
| 601 | `MeshTopologyPackage` | Mesh topology (
|
|
523
|
-
| 602 | `MeshAlertPackage` | Mesh alerts (
|
|
524
|
-
| 603 | `MeshBridgePackage` | Mesh bridge (
|
|
555
|
+
| 204 | `MetricsPackage` | Sensor metrics (schema v0.7.2+) | `cpuUsage`, `freeHeap`, `bytesReceived`, `currentThroughput`, `connectionQuality`, `wifiRSSI` |
|
|
556
|
+
| 400 | `CommandPackage` | Device control | `command`, `targetDevice`, `parameters`, `commandId` |
|
|
557
|
+
| 600 | `MeshNodeListPackage` | Mesh node list (`MESH_NODE_LIST`) | `nodes[]` (nodeId, status, lastSeen, signalStrength), `nodeCount`, `meshId` |
|
|
558
|
+
| 601 | `MeshTopologyPackage` | Mesh topology (`MESH_TOPOLOGY`) | `connections[]` (fromNode, toNode, linkQuality, latencyMs), `rootNode` |
|
|
559
|
+
| 602 | `MeshAlertPackage` | Mesh alerts (`MESH_ALERT`) | `alerts[]` (alertType, severity, message, nodeId), `alertCount` |
|
|
560
|
+
| 603 | `MeshBridgePackage` | Mesh bridge (`MESH_BRIDGE`) | `meshProtocol`, `fromNodeId`, `toNodeId`, `meshType`, `rawPayload`, `rssi`, `hopCount` |
|
|
525
561
|
| 604 | `EnhancedStatusPackage` | Mesh status (MESH_STATUS per schema v0.7.2+) | `nodeCount`, `connectionCount`, `messagesReceived`, `messagesSent`, `avgLatency`, `packetLossRate` |
|
|
526
|
-
| 605 | `HealthCheckPackage` | Mesh metrics (
|
|
527
|
-
| 610 | `BridgeStatusPackage` | Bridge health monitoring (
|
|
528
|
-
| 611 | `BridgeElectionPackage` | Bridge failover election (
|
|
529
|
-
| 612 | `BridgeTakeoverPackage` | Bridge role announcement (
|
|
530
|
-
| 613 | `BridgeCoordinationPackage` | Multi-bridge coordination (
|
|
531
|
-
| 614 | `NTPTimeSyncPackage` | NTP time synchronization (
|
|
562
|
+
| 605 | `HealthCheckPackage` | Mesh metrics (`MESH_METRICS`, schema v0.7.2+) | `healthStatus`, `problemFlags`, `memoryHealth`, `networkHealth`, `performanceHealth`, `recommendations` |
|
|
563
|
+
| 610 | `BridgeStatusPackage` | Bridge health monitoring (`BRIDGE_STATUS`) | `internetConnected`, `routerRSSI`, `routerChannel`, `uptime`, `gatewayIP`, `timestamp` |
|
|
564
|
+
| 611 | `BridgeElectionPackage` | Bridge failover election (`BRIDGE_ELECTION`) | `routerRSSI`, `routerChannel`, `uptime`, `freeMemory`, `timestamp`, `routerSSID` |
|
|
565
|
+
| 612 | `BridgeTakeoverPackage` | Bridge role announcement (`BRIDGE_TAKEOVER`) | `previousBridge`, `reason`, `routerChannel`, `timestamp` |
|
|
566
|
+
| 613 | `BridgeCoordinationPackage` | Multi-bridge coordination (`BRIDGE_COORDINATION`) | `priority`, `role`, `peerBridges[]`, `load`, `timestamp` |
|
|
567
|
+
| 614 | `NTPTimeSyncPackage` | NTP time synchronization (`TIME_SYNC_NTP`) | `ntpTime`, `accuracy`, `source`, `timestamp` |
|
|
532
568
|
|
|
533
569
|
## Key Features
|
|
534
570
|
|
|
@@ -560,54 +596,23 @@ These are the message types used by applications built on painlessMesh:
|
|
|
560
596
|
- **Event Coordination** - Synchronized displays, distributed processing
|
|
561
597
|
- **Bridge Networks** - Connect mesh to WiFi/Internet/MQTT - [📖 Bridge Guide](BRIDGE_TO_INTERNET.md)
|
|
562
598
|
|
|
563
|
-
## Latest Release:
|
|
564
|
-
|
|
565
|
-
**Tunable TCP Connect-Retry Behaviour (issue #378)**
|
|
566
|
-
|
|
567
|
-
- The five TCP connect-retry values that were hardcoded in `tcp.hpp` are now tunable per mesh instance via `mesh.setTcpRetryConfig()` / `mesh.getTcpRetryConfig()` (#378, PR #395)
|
|
568
|
-
- Defaults match the previous constants exactly — **no behaviour change unless you call the setter**
|
|
569
|
-
- New `examples/tcpRetryConfig/` with real-time, high-reliability and battery-saver profiles
|
|
570
|
-
- `MessageQueue` documentation corrected: it is a manual buffer, never an auto-flush queue (#385)
|
|
571
|
-
- `MIN_FREE_MEMORY` / `MAX_MESSAGE_QUEUE` deprecated as ignored no-ops, values preserved for source compatibility (#385)
|
|
572
|
-
- Fixed `bridge_failover` example failing to compile on an unqualified `plugin::` type (#360)
|
|
573
|
-
|
|
574
|
-
> **npm users:** v1.9.21 was never published to npm ([#381](https://github.com/Alteriom/painlessMesh/issues/381) — expired token). npm's previous version is 1.9.20, so upgrading from npm picks up both releases. GitHub, PlatformIO and Arduino were unaffected.
|
|
575
|
-
|
|
576
|
-
**Previous Release: v1.9.21 (August 4, 2026)**
|
|
577
|
-
|
|
578
|
-
**Crash Fixes: Task & TCP Connection Lifecycle (issue #373)**
|
|
579
|
-
|
|
580
|
-
- Fixed use-after-free in `Task::disable()` that crashed nodes on every peer disconnect (#373, PR #376 by @vaz82)
|
|
581
|
-
- Fixed `PackageHandler::stop()` destroying the currently-executing task during bridge promotion
|
|
582
|
-
- Fixed stale-pcb heap corruption window in `~BufferedConnection()` and an `onError`/`onConnect` double-handling race
|
|
583
|
-
- New AddressSanitizer CI job and regression test for the task/connection cleanup lifecycle
|
|
599
|
+
## Latest Release: v2.0.0 (September 7, 2026)
|
|
584
600
|
|
|
585
|
-
**
|
|
601
|
+
**Delivery confirmation, a unified send path, and a mesh that holds together on real hardware**
|
|
586
602
|
|
|
587
|
-
-
|
|
588
|
-
-
|
|
589
|
-
-
|
|
590
|
-
-
|
|
591
|
-
-
|
|
592
|
-
- Documentation consistency audit — fixed broken links, API examples, version references
|
|
593
|
-
|
|
594
|
-
**Recent Key Features (v1.9.0 - v1.9.16):**
|
|
595
|
-
|
|
596
|
-
- 🔍 **Mesh Connectivity Detection** - New `hasActiveMeshConnections()` and `getLastKnownBridge()` APIs
|
|
597
|
-
- 🌉 **Improved Bridge Detection** - `getPrimaryBridge()` returns last known bridge when disconnected
|
|
598
|
-
- ⚡ **Enhanced TCP Reliability** - Exponential backoff and increased retries for mesh connections
|
|
599
|
-
- 🛡️ **Race Condition Fixes** - Improved bridge status and connection validation
|
|
600
|
-
- 📦 **Consolidated Examples** - Streamlined to 15 essential examples
|
|
601
|
-
- ⚙️ **Configurable Election Timing** - Prevent split-brain with `setElectionStartupDelay()` and `setElectionRandomDelay()`
|
|
603
|
+
- `sendSingle()` and `sendBroadcast()` accept a delivery callback — it fires with `delivered=true` and the round-trip latency on acknowledgment, or `delivered=false` on timeout — and a `SendOptions` struct that carries a priority and a callback in one call. Priority is kept across hops.
|
|
604
|
+
- Thirty-odd defects in gateway failover, channel following, routing and the station scan, every one found in the serial logs of a six-family hardware rig and fixed there: a bridge that stops says so, the mesh follows an elected bridge to its channel and treats it as home, a node is in one place in every neighbour's tree, a dead connection is not a route, a stale scan does not consume a live one.
|
|
605
|
+
- The ESP32-C5 and ESP32-C6 (Arduino core 3.x) no longer hang after a channel follow; the ESP8266 is specified for small meshes or as a leaf, and says so at runtime.
|
|
606
|
+
- Gateway HTTP work is bounded by `NODE_TIMEOUT`, so an Internet request can no longer partition the mesh around its own gateway.
|
|
607
|
+
- The release candidate passed the rig's whole suite three times in a row. Delivery confirmation and cross-hop priority need 2.0 on every node of the path.
|
|
602
608
|
|
|
603
609
|
**[📋 Full CHANGELOG](CHANGELOG.md)**
|
|
604
610
|
|
|
605
611
|
## Getting Help
|
|
606
612
|
|
|
607
|
-
- **[
|
|
608
|
-
- **[
|
|
613
|
+
- **[Troubleshooting](USER_GUIDE.md#troubleshooting)** - Common issues, debug configuration, best practices
|
|
614
|
+
- **[FAQ](docsify-site/troubleshooting/faq.md)** - Frequently asked questions
|
|
609
615
|
- **[GitHub Issues](https://github.com/Alteriom/painlessMesh/issues)** - Bug reports and feature requests
|
|
610
|
-
- **[Community Forum](https://groups.google.com/forum/#!forum/painlessmesh-user)** - Community support
|
|
611
616
|
- **[API Documentation](https://alteriom.github.io/painlessMesh/#/api/doxygen)** - Generated API docs
|
|
612
617
|
|
|
613
618
|
## Development
|
|
@@ -625,7 +630,8 @@ run-parts --regex catch_ bin/ # Run tests
|
|
|
625
630
|
|
|
626
631
|
### Requirements
|
|
627
632
|
|
|
628
|
-
- **ESP32
|
|
633
|
+
- **ESP32**: Arduino core 2.0.x or 3.x; the ESP32-C5 and ESP32-C6 need 3.x
|
|
634
|
+
- **ESP8266**: Arduino core 3.x
|
|
629
635
|
- **Dependencies**: ArduinoJson 7.x, TaskScheduler 4.x
|
|
630
636
|
- **Development**: CMake, Ninja, Boost (for desktop testing)
|
|
631
637
|
|
|
@@ -678,7 +684,7 @@ painlessMesh features a state-of-the-art automated CI/CD pipeline:
|
|
|
678
684
|
./scripts/validate-release.sh # Validate release readiness
|
|
679
685
|
|
|
680
686
|
# Edit CHANGELOG.md, then commit with release prefix
|
|
681
|
-
git commit -am "release:
|
|
687
|
+
git commit -am "release: vX.Y.Z"
|
|
682
688
|
git push origin main # Triggers automated release
|
|
683
689
|
```
|
|
684
690
|
|
|
@@ -686,13 +692,8 @@ See [RELEASE_GUIDE.md](RELEASE_GUIDE.md) for complete release documentation.
|
|
|
686
692
|
|
|
687
693
|
## Contributing
|
|
688
694
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
## Funding
|
|
692
|
-
|
|
693
|
-
If you like the library please consider supporting its development. Your contributions help me spend more time improving painlessMesh.
|
|
695
|
+
Pull requests go to `Feat/next-release`, the integration branch for the next version; `main` holds released code and a push to it publishes a release. For branches, tests and what a pull request needs to show, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
694
696
|
|
|
695
|
-
**[Donate via PayPal](https://www.paypal.com/paypalme/domlavoie)** • [dominic.lavoie@gmail.com](mailto:dominic.lavoie@gmail.com)
|
|
696
697
|
|
|
697
698
|
## 📚 Documentation
|
|
698
699
|
|
|
@@ -708,18 +709,18 @@ If you like the library please consider supporting its development. Your contrib
|
|
|
708
709
|
### 🚀 Quick Links
|
|
709
710
|
|
|
710
711
|
**New to AlteriomPainlessMesh?**
|
|
711
|
-
- [Quick Start](USER_GUIDE.md) - Get your first mesh running in 5 minutes
|
|
712
|
-
- [Installation](USER_GUIDE.md) - Arduino IDE and PlatformIO setup
|
|
713
|
-
- [First Mesh](USER_GUIDE.md) - Build a multi-node network
|
|
712
|
+
- [Quick Start](USER_GUIDE.md#getting-started) - Get your first mesh running in 5 minutes
|
|
713
|
+
- [Installation](USER_GUIDE.md#installation) - Arduino IDE and PlatformIO setup
|
|
714
|
+
- [First Mesh](USER_GUIDE.md#your-first-mesh-network) - Build a multi-node network
|
|
714
715
|
|
|
715
716
|
**Reference Documentation:**
|
|
716
|
-
- [Core API](USER_GUIDE.md) - painlessMesh class methods
|
|
717
|
+
- [Core API](USER_GUIDE.md#api-reference) - painlessMesh class methods
|
|
717
718
|
- [Alteriom Extensions](examples/alteriom/README.md) - SensorPackage, CommandPackage, StatusPackage
|
|
718
|
-
- [Examples](examples/) -
|
|
719
|
+
- [Examples](examples/) - 18 example directories, 21 sketches, every one compiled for esp32 and esp8266 on each pull request; [.github/DOCUMENTATION.md](.github/DOCUMENTATION.md) lists what each shows
|
|
719
720
|
|
|
720
721
|
**Need Help?**
|
|
721
|
-
- [
|
|
722
|
-
- [
|
|
722
|
+
- [Troubleshooting](USER_GUIDE.md#troubleshooting) - Common issues and how to read the logs
|
|
723
|
+
- [FAQ](docsify-site/troubleshooting/faq.md) - Frequently asked questions
|
|
723
724
|
- [GitHub Issues](https://github.com/Alteriom/painlessMesh/issues) - Bug reports and support
|
|
724
725
|
|
|
725
726
|
## 🔧 Quick API Reference
|
|
@@ -755,7 +756,11 @@ mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
|
755
756
|
|
|
756
757
|
**For complete API documentation, see [USER_GUIDE.md](USER_GUIDE.md#api-reference) or [online docs](https://alteriom.github.io/painlessMesh/#/api/core-api).**
|
|
757
758
|
|
|
758
|
-
|
|
759
|
+
## Funding
|
|
760
|
+
|
|
761
|
+
If you like the library please consider supporting its development. Your contributions help me spend more time improving painlessMesh.
|
|
762
|
+
|
|
763
|
+
**[Donate via PayPal](https://www.paypal.com/paypalme/domlavoie)** • [dominic.lavoie@gmail.com](mailto:dominic.lavoie@gmail.com)
|
|
759
764
|
|
|
760
765
|
Most development of painlessMesh has been done as a hobby, but some specific features have been funded by the companies listed below:
|
|
761
766
|
|