@alteriom/painlessmesh 1.8.5 → 1.8.6
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/CHANGELOG.md +27 -0
- package/examples/bridge_failover/README.md +63 -10
- package/examples/bridge_failover/bridge_failover.ino +16 -4
- package/library.json +1 -1
- package/library.properties +1 -1
- package/package.json +1 -1
- package/src/arduino/wifi.hpp +38 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.8.6] - 2025-11-12
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Bridge Failover Auto-Election (Issue #117)** - Bridge election now triggers when no initial bridge exists
|
|
15
|
+
- Added periodic monitoring task (30s interval) that detects absence of healthy bridge
|
|
16
|
+
- Activates after 60s startup grace period to allow network stabilization
|
|
17
|
+
- Randomized election delay (1-3s) prevents thundering herd problem
|
|
18
|
+
- Respects existing safeguards: election state, 60s cooldown, router visibility
|
|
19
|
+
- **Before**: No initial bridge → no election → mesh stays bridgeless indefinitely
|
|
20
|
+
- **After**: No initial bridge → 60s startup → monitoring detects absence → election triggered → best RSSI node becomes bridge
|
|
21
|
+
- Fully backward compatible: pre-designated bridge mode continues to work as before
|
|
22
|
+
- Core fix in `src/arduino/wifi.hpp`
|
|
23
|
+
- Resolves @woodlist's "Bridge_failover example does not work" issue
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **bridge_failover Example Documentation** - Clarified two deployment modes
|
|
28
|
+
- Auto-Election Mode: All nodes regular (`INITIAL_BRIDGE=false`), RSSI-based election after 60s
|
|
29
|
+
- Pre-Designated Mode: Traditional single initial bridge setup
|
|
30
|
+
- Updated README.md with comprehensive auto-election documentation
|
|
31
|
+
- Enhanced header comments in bridge_failover.ino
|
|
32
|
+
|
|
33
|
+
### Housekeeping
|
|
34
|
+
|
|
35
|
+
- Synchronized package-lock.json version to 1.8.5
|
|
36
|
+
|
|
10
37
|
## [1.8.5] - 2025-11-12
|
|
11
38
|
|
|
12
39
|
### Fixed
|
|
@@ -30,10 +30,20 @@ Regular nodes track these broadcasts and detect failures when:
|
|
|
30
30
|
|
|
31
31
|
### 2. Election Trigger
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
An election is triggered when:
|
|
34
|
+
|
|
35
|
+
**Scenario 1: No Bridge Exists (Auto-Election Mode)**
|
|
36
|
+
- After 60-second startup period
|
|
37
|
+
- Periodic monitoring (every 30s) detects no healthy bridge
|
|
34
38
|
- Nodes with router credentials configured start an election
|
|
35
39
|
- Nodes without credentials remain passive
|
|
36
40
|
|
|
41
|
+
**Scenario 2: Bridge Failure**
|
|
42
|
+
- Primary bridge fails or loses Internet connectivity
|
|
43
|
+
- No status received within 60 seconds (configurable timeout)
|
|
44
|
+
- Bridge reports `internetConnected: false`
|
|
45
|
+
- Nodes detect failure and start election
|
|
46
|
+
|
|
37
47
|
### 3. Election Protocol
|
|
38
48
|
|
|
39
49
|
**Step 1: Candidacy Broadcast (Type 611)**
|
|
@@ -97,34 +107,77 @@ To prevent oscillation:
|
|
|
97
107
|
|
|
98
108
|
## Setup Instructions
|
|
99
109
|
|
|
100
|
-
|
|
110
|
+
You can choose between two deployment modes:
|
|
111
|
+
|
|
112
|
+
### Option A: Auto-Election Mode (Recommended)
|
|
113
|
+
|
|
114
|
+
**Best for**: Equal peers where any node can become the bridge based on signal strength.
|
|
115
|
+
|
|
116
|
+
1. Keep `INITIAL_BRIDGE = false` on **ALL nodes**
|
|
117
|
+
2. Configure mesh credentials (MESH_PREFIX, MESH_PASSWORD)
|
|
118
|
+
3. Configure router credentials (ROUTER_SSID, ROUTER_PASSWORD)
|
|
119
|
+
4. Flash the same sketch to all ESP32/ESP8266 devices
|
|
120
|
+
5. Power on all nodes simultaneously
|
|
121
|
+
|
|
122
|
+
**What happens**:
|
|
123
|
+
- Nodes start as regular mesh nodes
|
|
124
|
+
- After 60-second startup period, automatic monitoring begins
|
|
125
|
+
- If no bridge exists, nodes trigger an election
|
|
126
|
+
- Node with best router RSSI wins and becomes bridge
|
|
127
|
+
- Other nodes remain regular with failover capability
|
|
128
|
+
|
|
129
|
+
**Advantages**:
|
|
130
|
+
- Simpler setup - no need to designate a specific node
|
|
131
|
+
- True dynamic failover - any node can become bridge
|
|
132
|
+
- Best bridge selected based on signal strength
|
|
133
|
+
|
|
134
|
+
### Option B: Pre-Designated Bridge Mode
|
|
135
|
+
|
|
136
|
+
**Best for**: When you want a specific node to start as the bridge.
|
|
137
|
+
|
|
138
|
+
**1. Flash Initial Bridge Node**
|
|
101
139
|
|
|
102
140
|
1. Set `INITIAL_BRIDGE` to `true`
|
|
103
141
|
2. Configure router credentials
|
|
104
142
|
3. Flash to one ESP32/ESP8266
|
|
105
143
|
4. This node will connect to router and start as bridge
|
|
106
144
|
|
|
107
|
-
|
|
145
|
+
**2. Flash Regular Nodes**
|
|
108
146
|
|
|
109
147
|
1. Set `INITIAL_BRIDGE` to `false`
|
|
110
148
|
2. Configure same mesh and router credentials
|
|
111
149
|
3. Flash to other ESP32/ESP8266 devices
|
|
112
150
|
4. These nodes can become bridges via election
|
|
113
151
|
|
|
114
|
-
|
|
152
|
+
**Advantages**:
|
|
153
|
+
- Immediate bridge availability (no 60s wait)
|
|
154
|
+
- Predictable initial bridge selection
|
|
155
|
+
- Good for nodes with fixed locations
|
|
156
|
+
|
|
157
|
+
### Test Failover Scenarios
|
|
158
|
+
|
|
159
|
+
**Scenario 1: Auto-Election (No Initial Bridge)**
|
|
160
|
+
1. Flash all nodes with `INITIAL_BRIDGE = false`
|
|
161
|
+
2. Power on all nodes
|
|
162
|
+
3. Wait 60 seconds for startup period
|
|
163
|
+
4. Automatic monitoring detects no bridge
|
|
164
|
+
5. Election starts automatically within 30 seconds
|
|
165
|
+
6. Node with best router signal becomes bridge
|
|
166
|
+
7. Monitor serial output to see election process
|
|
115
167
|
|
|
116
|
-
**Scenario
|
|
117
|
-
1. Power off the
|
|
168
|
+
**Scenario 2: Bridge Goes Offline**
|
|
169
|
+
1. Power off the current bridge node (initial or elected)
|
|
118
170
|
2. After 60 seconds, regular nodes detect failure
|
|
119
171
|
3. Election starts automatically
|
|
120
172
|
4. Node with best router signal becomes new bridge
|
|
121
173
|
5. Monitor serial output to see election process
|
|
122
174
|
|
|
123
|
-
**Scenario
|
|
124
|
-
1. Disconnect router from Internet
|
|
175
|
+
**Scenario 3: Bridge Loses Internet**
|
|
176
|
+
1. Disconnect router from Internet (or block bridge node's Internet)
|
|
125
177
|
2. Bridge reports `internetConnected: false`
|
|
126
|
-
3.
|
|
127
|
-
4.
|
|
178
|
+
3. Nodes detect loss of Internet via status broadcasts
|
|
179
|
+
4. Election starts to find a node with working Internet
|
|
180
|
+
5. New bridge elected if another node has Internet access
|
|
128
181
|
|
|
129
182
|
## Serial Output
|
|
130
183
|
|
|
@@ -9,14 +9,26 @@
|
|
|
9
9
|
// - ESP32 or ESP8266
|
|
10
10
|
// - WiFi router with Internet connection
|
|
11
11
|
//
|
|
12
|
-
// Setup:
|
|
12
|
+
// Setup Options:
|
|
13
|
+
//
|
|
14
|
+
// OPTION A - Auto-Election Mode (Recommended):
|
|
15
|
+
// 1. Configure your mesh credentials (MESH_PREFIX, MESH_PASSWORD)
|
|
16
|
+
// 2. Configure your router credentials (ROUTER_SSID, ROUTER_PASSWORD)
|
|
17
|
+
// 3. Keep INITIAL_BRIDGE = false on ALL nodes
|
|
18
|
+
// 4. Flash multiple nodes with this sketch
|
|
19
|
+
// 5. After startup (~60 seconds), nodes will automatically elect a bridge
|
|
20
|
+
// based on best router signal strength (RSSI)
|
|
21
|
+
//
|
|
22
|
+
// OPTION B - Pre-Designated Bridge Mode:
|
|
13
23
|
// 1. Configure your mesh credentials (MESH_PREFIX, MESH_PASSWORD)
|
|
14
24
|
// 2. Configure your router credentials (ROUTER_SSID, ROUTER_PASSWORD)
|
|
15
|
-
// 3.
|
|
16
|
-
// 4.
|
|
17
|
-
// 5.
|
|
25
|
+
// 3. Set INITIAL_BRIDGE = true on ONE node (your designated bridge)
|
|
26
|
+
// 4. Keep INITIAL_BRIDGE = false on all other nodes
|
|
27
|
+
// 5. Flash the nodes - designated bridge starts immediately
|
|
28
|
+
// 6. If designated bridge fails, others will hold election
|
|
18
29
|
//
|
|
19
30
|
// Features Demonstrated:
|
|
31
|
+
// - Automatic bridge election when no bridge exists
|
|
20
32
|
// - Automatic bridge failure detection via heartbeats
|
|
21
33
|
// - RSSI-based election protocol
|
|
22
34
|
// - Deterministic winner selection with tiebreakers
|
package/library.json
CHANGED
package/library.properties
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name=Alteriom PainlessMesh
|
|
2
|
-
version=1.8.
|
|
2
|
+
version=1.8.6
|
|
3
3
|
author=Coopdis,Scotty Franzyshen,Edwin van Leeuwen,Germán Martín,Maximilian Schwarz,Doanh Doanh,Alteriom
|
|
4
4
|
maintainer=Alteriom
|
|
5
5
|
sentence=A painless way to setup a mesh with ESP8266 and ESP32 devices with Alteriom extensions
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alteriom/painlessmesh",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.6",
|
|
4
4
|
"description": "painlessMesh is a user-friendly library for creating mesh networks with ESP8266 and ESP32 devices. This Alteriom fork includes additional packages for sensor data (SensorPackage), device commands (CommandPackage), and status monitoring (StatusPackage). It handles routing and network management automatically, so you can focus on your application. The library uses JSON-based messaging and syncs time across all nodes, making it ideal for coordinated behaviour like synchronized light displays or sensor networks reporting to a central node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"arduino",
|
package/src/arduino/wifi.hpp
CHANGED
|
@@ -155,6 +155,44 @@ class Mesh : public painlessmesh::Mesh<Connection> {
|
|
|
155
155
|
}
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
+
// Add periodic monitoring task to detect when no bridge exists
|
|
159
|
+
// This handles the case where no node was initially configured as a bridge
|
|
160
|
+
this->addTask(30000, TASK_FOREVER, [this]() {
|
|
161
|
+
// Only check if failover is enabled and we have credentials
|
|
162
|
+
if (!bridgeFailoverEnabled || !routerCredentialsConfigured) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Don't check if we're already a bridge
|
|
167
|
+
if (this->isBridge()) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Skip check during startup period (60 seconds) to allow initial bridge discovery
|
|
172
|
+
if (millis() < 60000) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Check if there are any healthy bridges
|
|
177
|
+
bool hasHealthyBridge = false;
|
|
178
|
+
for (const auto& bridge : this->getBridges()) {
|
|
179
|
+
if (bridge.isHealthy(bridgeTimeoutMs) && bridge.internetConnected) {
|
|
180
|
+
hasHealthyBridge = true;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// If no healthy bridge exists, trigger an election
|
|
186
|
+
if (!hasHealthyBridge) {
|
|
187
|
+
Log(CONNECTION, "Bridge monitor: No healthy bridge detected, triggering election\n");
|
|
188
|
+
// Small delay to randomize election start across nodes
|
|
189
|
+
uint32_t randomDelay = random(1000, 3000);
|
|
190
|
+
this->addTask(randomDelay, TASK_ONCE, [this]() {
|
|
191
|
+
this->startBridgeElection();
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
158
196
|
tcpServerInit();
|
|
159
197
|
eventHandleInit();
|
|
160
198
|
|