@alteriom/painlessmesh 1.9.20 → 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 +604 -0
- package/CONTRIBUTING.md +56 -53
- package/README.md +100 -75
- package/RELEASE_GUIDE.md +81 -641
- package/examples/alteriom/README.md +8 -10
- package/examples/alteriom/alteriom.ino +2 -2
- package/examples/alteriom/alteriom_custom_package_template.hpp +11 -11
- 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} +5 -1
- package/examples/basic/test/simulator/README.md +3 -3
- package/examples/bridge_failover/README.md +51 -14
- package/examples/bridge_failover/bridge_failover.ino +2 -2
- 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/examples/tcpRetryConfig/README.md +110 -0
- package/examples/tcpRetryConfig/platformio.ini +26 -0
- package/examples/tcpRetryConfig/tcpRetryConfig.ino +154 -0
- package/keywords.txt +53 -1
- package/library.json +8 -6
- package/library.properties +2 -2
- package/package.json +3 -3
- package/src/AlteriomPainlessMesh.h +4 -4
- package/src/arduino/wifi.hpp +605 -143
- package/src/painlessMesh.h +2 -2
- package/src/painlessMeshSTA.cpp +607 -87
- package/src/painlessMeshSTA.h +135 -3
- package/src/painlessTaskOptions.h +9 -0
- package/src/painlessmesh/ack.hpp +283 -0
- package/src/painlessmesh/buffer.hpp +74 -9
- package/src/painlessmesh/callback.hpp +38 -5
- package/src/painlessmesh/configuration.hpp +82 -3
- package/src/painlessmesh/connection.hpp +43 -16
- 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 +625 -70
- package/src/painlessmesh/message_queue.hpp +24 -13
- package/src/painlessmesh/ntp.hpp +2 -4
- package/src/painlessmesh/plugin.hpp +52 -6
- package/src/painlessmesh/protocol.hpp +55 -2
- package/src/painlessmesh/router.hpp +192 -77
- package/src/painlessmesh/tcp.hpp +168 -29
- 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/CONTRIBUTING.md
CHANGED
|
@@ -1,79 +1,82 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Branches
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- `main` holds released code. A push to `main` that carries a version bump,
|
|
6
|
+
or whose head commit message starts with `release:`, is what tags and
|
|
7
|
+
publishes a release (see [RELEASE_GUIDE.md](RELEASE_GUIDE.md)).
|
|
8
|
+
- `Feat/next-release` is the integration branch for the next version. Open
|
|
9
|
+
pull requests against it.
|
|
10
|
+
- Work happens on short-lived feature branches (`fix/…`, `feat/…`, `docs/…`)
|
|
11
|
+
cut from `Feat/next-release`.
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
Maintainers merge quickly, often as a squash. Push every commit you describe
|
|
14
|
+
before you describe it, and cut follow-up work from the merged base rather
|
|
15
|
+
than from a stale branch.
|
|
8
16
|
|
|
9
|
-
## Submit a pull request
|
|
17
|
+
## Submit a pull request
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
- Point the pull request at `Feat/next-release`, not `main`.
|
|
20
|
+
- Say what was wrong, how you know (a log, a test, a measurement), and what
|
|
21
|
+
the change does about it. For anything that touches the radio, routing,
|
|
22
|
+
the gateway or OTA, the evidence is a serial log or a run on the
|
|
23
|
+
hardware-in-the-loop rig; a unit test alone is not enough there, because
|
|
24
|
+
the unit tests mock the radio.
|
|
25
|
+
- Get your code reviewed by another contributor, and let the reviewer merge.
|
|
16
26
|
|
|
17
|
-
|
|
27
|
+
Tests must pass for the code to be merged. Add a changelog entry under
|
|
28
|
+
`## [Unreleased]` in [CHANGELOG.md](CHANGELOG.md) for any user-visible change.
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
## Testing requirements
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
### Running the desktop tests
|
|
22
33
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Before submitting a pull request, ensure all tests pass:
|
|
34
|
+
Before submitting a pull request, build and run the Catch2 and Boost suites:
|
|
26
35
|
|
|
27
36
|
```bash
|
|
28
|
-
|
|
37
|
+
git submodule update --init
|
|
29
38
|
cmake -G Ninja .
|
|
30
39
|
ninja
|
|
31
40
|
run-parts --regex catch_ bin/
|
|
32
|
-
|
|
33
|
-
# Run simulator tests (for examples)
|
|
34
|
-
cd test/simulator
|
|
35
|
-
mkdir build && cd build
|
|
36
|
-
cmake -G Ninja .. && ninja
|
|
37
|
-
bin/painlessmesh-simulator --config ../../../examples/basic/test/simulator/scenarios/basic_mesh_test.yaml
|
|
38
41
|
```
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
1. **Unit Tests**: Add tests in `test/catch/` for new components
|
|
45
|
-
2. **Integration Tests**: Add to `test/boost/tcp_integration.cpp` for core functionality
|
|
46
|
-
3. **Simulator Tests**: Create test scenarios in `examples/your_example/test/simulator/` for new examples
|
|
47
|
-
4. **Documentation**: Update relevant test documentation
|
|
48
|
-
|
|
49
|
-
### Example Validation with Simulator
|
|
43
|
+
The same suites run in CI under gcc, clang and AddressSanitizer, and CI also
|
|
44
|
+
compiles every example for esp32 and esp8266 with `arduino-cli`, builds the
|
|
45
|
+
PlatformIO projects under `test/ci/`, and checks formatting and library
|
|
46
|
+
metadata.
|
|
50
47
|
|
|
51
|
-
|
|
48
|
+
### Simulator and hardware tests
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
Multi-node behaviour is tested with the external
|
|
51
|
+
[painlessMesh-simulator](https://github.com/Alteriom/painlessMesh-simulator);
|
|
52
|
+
scenarios for an example live under `examples/<example>/test/simulator/`
|
|
53
|
+
(see `examples/basic/test/simulator/`). Radio, routing, gateway, failover
|
|
54
|
+
and OTA behaviour is validated on the Alteriom hardware-in-the-loop farm; a
|
|
55
|
+
maintainer runs it on a pull request by adding the `run-hil` label, and the
|
|
56
|
+
release gate is three consecutive clean runs of the whole suite.
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
### Adding tests for new features
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
1. **Unit tests**: add to `test/catch/` for new components.
|
|
61
|
+
2. **Integration tests**: add to `test/boost/tcp_integration.cpp` for core
|
|
62
|
+
behaviour that spans connections.
|
|
63
|
+
3. **Simulator scenarios**: add YAML scenarios under
|
|
64
|
+
`examples/<example>/test/simulator/` for new examples.
|
|
65
|
+
4. **Documentation**: keep `USER_GUIDE.md`, `README.md` and the example's
|
|
66
|
+
own README in step with the change.
|
|
64
67
|
|
|
65
68
|
## Versioning
|
|
66
69
|
|
|
67
|
-
This project
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
Major.Minor.Patch
|
|
72
|
-
|
|
73
|
-
A major version bump means that a massive change took place and that application will probably have to be redeployed because a *backwards incompatible* version was released. Example: A library => model relationship change which requires previous configuration options to become invalid.
|
|
74
|
-
|
|
75
|
-
A minor version is a *backwards compatible* addition or change to the core software. Most development activity will be this type of version bump. Example: A new feature or model.
|
|
70
|
+
This project follows [semver](https://semver.org/). Version 2.0 patch
|
|
71
|
+
releases must remain wire-compatible with the 2.0 protocol; anything that
|
|
72
|
+
changes what a node puts on the wire, or what an existing sketch has to do to
|
|
73
|
+
keep working, is a major version.
|
|
76
74
|
|
|
77
|
-
|
|
75
|
+
- **Major**: a backwards-incompatible change (a new or changed protocol
|
|
76
|
+
message, a removed API).
|
|
77
|
+
- **Minor**: a backwards-compatible addition.
|
|
78
|
+
- **Patch**: a backwards-compatible fix.
|
|
78
79
|
|
|
79
|
-
Documentation
|
|
80
|
+
Documentation does not require a version bump. The three version files
|
|
81
|
+
(`library.properties`, `library.json`, `package.json`) are changed together
|
|
82
|
+
with `./scripts/bump-version.sh`.
|
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,34 +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
|
-
**Full Repo Cleanup, Bug Fixes & Bridge Coordination Callbacks**
|
|
599
|
+
## Latest Release: v2.0.0 (September 7, 2026)
|
|
566
600
|
|
|
567
|
-
|
|
568
|
-
- Fixed 13 critical/high/medium bugs (double-free, RSSI overflow, memory leaks, blocking delays)
|
|
569
|
-
- Removed ~3,600 lines of dead code and 40 AI-generated docs
|
|
570
|
-
- Fixed all CI/CD workflows (corrected action versions)
|
|
571
|
-
- Removed 15 fake test files, fixed test infrastructure
|
|
572
|
-
- Documentation consistency audit — fixed broken links, API examples, version references
|
|
601
|
+
**Delivery confirmation, a unified send path, and a mesh that holds together on real hardware**
|
|
573
602
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
-
|
|
577
|
-
-
|
|
578
|
-
-
|
|
579
|
-
- 🛡️ **Race Condition Fixes** - Improved bridge status and connection validation
|
|
580
|
-
- 📦 **Consolidated Examples** - Streamlined to 15 essential examples
|
|
581
|
-
- ⚙️ **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.
|
|
582
608
|
|
|
583
609
|
**[📋 Full CHANGELOG](CHANGELOG.md)**
|
|
584
610
|
|
|
585
611
|
## Getting Help
|
|
586
612
|
|
|
587
|
-
- **[
|
|
588
|
-
- **[
|
|
613
|
+
- **[Troubleshooting](USER_GUIDE.md#troubleshooting)** - Common issues, debug configuration, best practices
|
|
614
|
+
- **[FAQ](docsify-site/troubleshooting/faq.md)** - Frequently asked questions
|
|
589
615
|
- **[GitHub Issues](https://github.com/Alteriom/painlessMesh/issues)** - Bug reports and feature requests
|
|
590
|
-
- **[Community Forum](https://groups.google.com/forum/#!forum/painlessmesh-user)** - Community support
|
|
591
616
|
- **[API Documentation](https://alteriom.github.io/painlessMesh/#/api/doxygen)** - Generated API docs
|
|
592
617
|
|
|
593
618
|
## Development
|
|
@@ -605,7 +630,8 @@ run-parts --regex catch_ bin/ # Run tests
|
|
|
605
630
|
|
|
606
631
|
### Requirements
|
|
607
632
|
|
|
608
|
-
- **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
|
|
609
635
|
- **Dependencies**: ArduinoJson 7.x, TaskScheduler 4.x
|
|
610
636
|
- **Development**: CMake, Ninja, Boost (for desktop testing)
|
|
611
637
|
|
|
@@ -658,7 +684,7 @@ painlessMesh features a state-of-the-art automated CI/CD pipeline:
|
|
|
658
684
|
./scripts/validate-release.sh # Validate release readiness
|
|
659
685
|
|
|
660
686
|
# Edit CHANGELOG.md, then commit with release prefix
|
|
661
|
-
git commit -am "release:
|
|
687
|
+
git commit -am "release: vX.Y.Z"
|
|
662
688
|
git push origin main # Triggers automated release
|
|
663
689
|
```
|
|
664
690
|
|
|
@@ -666,13 +692,8 @@ See [RELEASE_GUIDE.md](RELEASE_GUIDE.md) for complete release documentation.
|
|
|
666
692
|
|
|
667
693
|
## Contributing
|
|
668
694
|
|
|
669
|
-
|
|
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).
|
|
670
696
|
|
|
671
|
-
## Funding
|
|
672
|
-
|
|
673
|
-
If you like the library please consider supporting its development. Your contributions help me spend more time improving painlessMesh.
|
|
674
|
-
|
|
675
|
-
**[Donate via PayPal](https://www.paypal.com/paypalme/domlavoie)** • [dominic.lavoie@gmail.com](mailto:dominic.lavoie@gmail.com)
|
|
676
697
|
|
|
677
698
|
## 📚 Documentation
|
|
678
699
|
|
|
@@ -688,18 +709,18 @@ If you like the library please consider supporting its development. Your contrib
|
|
|
688
709
|
### 🚀 Quick Links
|
|
689
710
|
|
|
690
711
|
**New to AlteriomPainlessMesh?**
|
|
691
|
-
- [Quick Start](USER_GUIDE.md) - Get your first mesh running in 5 minutes
|
|
692
|
-
- [Installation](USER_GUIDE.md) - Arduino IDE and PlatformIO setup
|
|
693
|
-
- [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
|
|
694
715
|
|
|
695
716
|
**Reference Documentation:**
|
|
696
|
-
- [Core API](USER_GUIDE.md) - painlessMesh class methods
|
|
717
|
+
- [Core API](USER_GUIDE.md#api-reference) - painlessMesh class methods
|
|
697
718
|
- [Alteriom Extensions](examples/alteriom/README.md) - SensorPackage, CommandPackage, StatusPackage
|
|
698
|
-
- [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
|
|
699
720
|
|
|
700
721
|
**Need Help?**
|
|
701
|
-
- [
|
|
702
|
-
- [
|
|
722
|
+
- [Troubleshooting](USER_GUIDE.md#troubleshooting) - Common issues and how to read the logs
|
|
723
|
+
- [FAQ](docsify-site/troubleshooting/faq.md) - Frequently asked questions
|
|
703
724
|
- [GitHub Issues](https://github.com/Alteriom/painlessMesh/issues) - Bug reports and support
|
|
704
725
|
|
|
705
726
|
## 🔧 Quick API Reference
|
|
@@ -735,7 +756,11 @@ mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
|
735
756
|
|
|
736
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).**
|
|
737
758
|
|
|
738
|
-
|
|
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)
|
|
739
764
|
|
|
740
765
|
Most development of painlessMesh has been done as a hobby, but some specific features have been funded by the companies listed below:
|
|
741
766
|
|