@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 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
- When the primary bridge fails:
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
- ### 1. Flash Initial Bridge Node
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
- ### 2. Flash Regular Nodes
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
- ### 3. Test Failover
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 1: Bridge Goes Offline**
117
- 1. Power off the initial bridge node
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 2: Bridge Loses Internet**
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. Election may start (nodes decide if failover needed)
127
- 4. New bridge elected if necessary
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. Flash multiple nodes with this sketch
16
- // 4. Designate one as the initial bridge by calling mesh.initAsBridge()
17
- // 5. Other nodes will automatically participate in elections if bridge fails
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
@@ -6,7 +6,7 @@
6
6
  "type": "git",
7
7
  "url": "https://github.com/Alteriom/painlessMesh"
8
8
  },
9
- "version": "1.8.5",
9
+ "version": "1.8.6",
10
10
  "frameworks": [
11
11
  "arduino"
12
12
  ],
@@ -1,5 +1,5 @@
1
1
  name=Alteriom PainlessMesh
2
- version=1.8.5
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.5",
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",
@@ -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