@alteriom/painlessmesh 1.7.9 → 1.8.1
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 +118 -2
- package/README.md +159 -12
- package/docs/BRIDGE_FAILOVER.md +512 -0
- package/docs/BRIDGE_HEALTH_MONITORING.md +293 -0
- package/docs/CREATE_MISSING_RELEASES.md +321 -0
- package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +523 -0
- package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +542 -0
- package/examples/alteriom/alteriom_sensor_package.hpp +213 -0
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +1014 -11
- package/examples/basic/basic.ino +6 -2
- package/examples/bridge/bridge.ino +44 -23
- package/examples/bridge/bridge_health_monitoring_example.ino +188 -0
- package/examples/bridgeAwareSensorNode/alteriom_sensor_package.hpp +1227 -0
- package/examples/bridgeAwareSensorNode/bridgeAwareSensorNode.ino +343 -0
- package/examples/bridgeAwareSensorNode/platformio.ini +26 -0
- package/examples/bridge_failover/README.md +358 -0
- package/examples/bridge_failover/bridge_failover.ino +180 -0
- package/examples/bridge_failover/platformio.ini +27 -0
- package/examples/diagnosticsExample/diagnosticsExample.ino +171 -0
- package/examples/diagnosticsExample/platformio.ini +26 -0
- package/examples/multi_bridge/README.md +346 -0
- package/examples/multi_bridge/primary_bridge.ino +96 -0
- package/examples/multi_bridge/regular_node.ino +141 -0
- package/examples/multi_bridge/secondary_bridge.ino +111 -0
- package/examples/ntpTimeSyncBridge/alteriom_sensor_package.hpp +1383 -0
- package/examples/ntpTimeSyncBridge/ntpTimeSyncBridge.ino +81 -0
- package/examples/ntpTimeSyncNode/alteriom_sensor_package.hpp +1383 -0
- package/examples/ntpTimeSyncNode/ntpTimeSyncNode.ino +109 -0
- package/examples/queued_alarms/README.md +390 -0
- package/examples/queued_alarms/queued_alarms.ino +265 -0
- package/examples/rtcIntegration/README.md +235 -0
- package/examples/rtcIntegration/rtcIntegration.ino +196 -0
- package/library.json +1 -1
- package/library.properties +1 -1
- package/package.json +1 -1
- package/src/arduino/wifi.hpp +888 -0
- package/src/painlessMeshSTA.cpp +63 -0
- package/src/painlessMeshSTA.h +3 -0
- package/src/painlessmesh/mesh.hpp +1327 -4
- package/src/painlessmesh/message_queue.hpp +368 -0
- package/src/painlessmesh/plugin.hpp +69 -0
- package/src/painlessmesh/rtc.hpp +203 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
//************************************************************
|
|
2
|
+
// Multi-Bridge Example: Regular Node
|
|
3
|
+
//
|
|
4
|
+
// This example demonstrates a regular mesh node in a multi-bridge
|
|
5
|
+
// network. The node automatically discovers and uses available bridges
|
|
6
|
+
// for Internet connectivity.
|
|
7
|
+
//
|
|
8
|
+
// Features demonstrated:
|
|
9
|
+
// - Automatic bridge discovery
|
|
10
|
+
// - Bridge selection awareness
|
|
11
|
+
// - Message routing to best available bridge
|
|
12
|
+
// - Failover handling
|
|
13
|
+
//************************************************************
|
|
14
|
+
|
|
15
|
+
#include "painlessMesh.h"
|
|
16
|
+
|
|
17
|
+
#define MESH_PREFIX "MultiBridgeMesh"
|
|
18
|
+
#define MESH_PASSWORD "meshpassword"
|
|
19
|
+
#define MESH_PORT 5555
|
|
20
|
+
|
|
21
|
+
Scheduler userScheduler;
|
|
22
|
+
painlessMesh mesh;
|
|
23
|
+
|
|
24
|
+
// Simulated sensor data
|
|
25
|
+
float temperature = 22.5;
|
|
26
|
+
float humidity = 45.0;
|
|
27
|
+
|
|
28
|
+
// Task to send sensor data
|
|
29
|
+
Task taskSendMessage(5000, TASK_FOREVER, [](){
|
|
30
|
+
// Simulate sensor readings
|
|
31
|
+
temperature += (random(-10, 10) / 10.0);
|
|
32
|
+
humidity += (random(-50, 50) / 10.0);
|
|
33
|
+
|
|
34
|
+
String msg = "Temperature: " + String(temperature, 1) + "°C, Humidity: " + String(humidity, 1) + "%";
|
|
35
|
+
|
|
36
|
+
Serial.println("\n--- Sending Sensor Data ---");
|
|
37
|
+
|
|
38
|
+
// Get recommended bridge
|
|
39
|
+
uint32_t recommendedBridge = mesh.getRecommendedBridge();
|
|
40
|
+
|
|
41
|
+
if (recommendedBridge != 0) {
|
|
42
|
+
Serial.printf("Recommended Bridge: %u\n", recommendedBridge);
|
|
43
|
+
Serial.printf("Message: %s\n", msg.c_str());
|
|
44
|
+
|
|
45
|
+
// Send to specific bridge
|
|
46
|
+
mesh.sendSingle(recommendedBridge, msg);
|
|
47
|
+
Serial.println("✓ Sent to bridge");
|
|
48
|
+
} else {
|
|
49
|
+
Serial.println("⚠️ No bridge available!");
|
|
50
|
+
Serial.println("Message queued for later delivery");
|
|
51
|
+
// In production, you would queue this message
|
|
52
|
+
}
|
|
53
|
+
Serial.println("---------------------------\n");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Task to display network status
|
|
57
|
+
Task taskNetworkStatus(15000, TASK_FOREVER, [](){
|
|
58
|
+
Serial.println("\n=== Network Status ===");
|
|
59
|
+
Serial.printf("Node ID: %u\n", mesh.getNodeId());
|
|
60
|
+
Serial.printf("Connected Nodes: %d\n", mesh.getNodeList().size());
|
|
61
|
+
|
|
62
|
+
// Show all active bridges
|
|
63
|
+
auto activeBridges = mesh.getActiveBridges();
|
|
64
|
+
Serial.printf("Active Bridges: %d\n", activeBridges.size());
|
|
65
|
+
|
|
66
|
+
if (activeBridges.empty()) {
|
|
67
|
+
Serial.println(" ⚠️ NO BRIDGES AVAILABLE");
|
|
68
|
+
} else {
|
|
69
|
+
for (auto bridgeId : activeBridges) {
|
|
70
|
+
Serial.printf(" - Bridge: %u\n", bridgeId);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Check Internet connectivity
|
|
75
|
+
bool hasInternet = mesh.hasInternetConnection();
|
|
76
|
+
Serial.printf("Internet Available: %s\n", hasInternet ? "YES" : "NO");
|
|
77
|
+
|
|
78
|
+
Serial.println("======================\n");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
void receivedCallback(uint32_t from, String& msg) {
|
|
82
|
+
Serial.printf("📨 Received from %u: %s\n", from, msg.c_str());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
void newConnectionCallback(uint32_t nodeId) {
|
|
86
|
+
Serial.printf("🔗 New Connection: %u\n", nodeId);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
void changedConnectionCallback() {
|
|
90
|
+
Serial.printf("🔄 Connections changed. Total nodes: %d\n", mesh.getNodeList().size());
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
void bridgeStatusCallback(uint32_t bridgeNodeId, bool hasInternet) {
|
|
94
|
+
Serial.printf("\n🌉 Bridge Status Update: Bridge %u - Internet %s\n",
|
|
95
|
+
bridgeNodeId, hasInternet ? "CONNECTED" : "OFFLINE");
|
|
96
|
+
|
|
97
|
+
if (hasInternet) {
|
|
98
|
+
Serial.println("✓ Internet connection available");
|
|
99
|
+
} else {
|
|
100
|
+
Serial.println("⚠️ Bridge lost Internet - checking for alternatives...");
|
|
101
|
+
|
|
102
|
+
auto activeBridges = mesh.getActiveBridges();
|
|
103
|
+
if (activeBridges.empty()) {
|
|
104
|
+
Serial.println("⚠️ No alternative bridges available!");
|
|
105
|
+
} else {
|
|
106
|
+
Serial.printf("✓ %d alternative bridge(s) available\n", activeBridges.size());
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
void setup() {
|
|
112
|
+
Serial.begin(115200);
|
|
113
|
+
delay(2000);
|
|
114
|
+
|
|
115
|
+
Serial.println("\n\n=== Multi-Bridge: REGULAR NODE ===\n");
|
|
116
|
+
|
|
117
|
+
// Initialize as regular mesh node
|
|
118
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
119
|
+
|
|
120
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
|
|
121
|
+
|
|
122
|
+
mesh.onReceive(&receivedCallback);
|
|
123
|
+
mesh.onNewConnection(&newConnectionCallback);
|
|
124
|
+
mesh.onChangedConnections(&changedConnectionCallback);
|
|
125
|
+
mesh.onBridgeStatusChanged(&bridgeStatusCallback);
|
|
126
|
+
|
|
127
|
+
// Add tasks
|
|
128
|
+
userScheduler.addTask(taskSendMessage);
|
|
129
|
+
userScheduler.addTask(taskNetworkStatus);
|
|
130
|
+
taskSendMessage.enable();
|
|
131
|
+
taskNetworkStatus.enable();
|
|
132
|
+
|
|
133
|
+
Serial.println("\n=== Regular Node Ready ===");
|
|
134
|
+
Serial.println("This node will automatically discover and use available bridges");
|
|
135
|
+
Serial.println("In multi-bridge mode, it will use the highest priority bridge");
|
|
136
|
+
Serial.println("If primary fails, it automatically switches to secondary\n");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
void loop() {
|
|
140
|
+
mesh.update();
|
|
141
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
//************************************************************
|
|
2
|
+
// Multi-Bridge Example: Secondary Bridge Node
|
|
3
|
+
//
|
|
4
|
+
// This example demonstrates a secondary bridge (priority 5) in a
|
|
5
|
+
// multi-bridge deployment. This provides hot standby redundancy
|
|
6
|
+
// and can handle load if the primary bridge is busy.
|
|
7
|
+
//
|
|
8
|
+
// Features demonstrated:
|
|
9
|
+
// - Secondary bridge with medium priority
|
|
10
|
+
// - Hot standby mode (always ready)
|
|
11
|
+
// - Automatic failover if primary fails
|
|
12
|
+
// - Load balancing support
|
|
13
|
+
//************************************************************
|
|
14
|
+
|
|
15
|
+
#include "painlessMesh.h"
|
|
16
|
+
|
|
17
|
+
#define MESH_PREFIX "MultiBridgeMesh"
|
|
18
|
+
#define MESH_PASSWORD "meshpassword"
|
|
19
|
+
#define MESH_PORT 5555
|
|
20
|
+
|
|
21
|
+
// Secondary router connection (backup Internet or different ISP)
|
|
22
|
+
#define ROUTER_SSID "SecondaryRouter"
|
|
23
|
+
#define ROUTER_PASSWORD "routerpass2"
|
|
24
|
+
|
|
25
|
+
Scheduler userScheduler;
|
|
26
|
+
painlessMesh mesh;
|
|
27
|
+
|
|
28
|
+
// Task to display bridge coordination status
|
|
29
|
+
Task taskBridgeStatus(10000, TASK_FOREVER, [](){
|
|
30
|
+
Serial.println("\n=== Secondary Bridge Status ===");
|
|
31
|
+
Serial.printf("Node ID: %u\n", mesh.getNodeId());
|
|
32
|
+
Serial.printf("Connected Nodes: %d\n", mesh.getNodeList().size());
|
|
33
|
+
|
|
34
|
+
// Show all active bridges in the mesh
|
|
35
|
+
auto activeBridges = mesh.getActiveBridges();
|
|
36
|
+
Serial.printf("Active Bridges: %d\n", activeBridges.size());
|
|
37
|
+
for (auto bridgeId : activeBridges) {
|
|
38
|
+
Serial.printf(" - Bridge: %u%s\n", bridgeId,
|
|
39
|
+
(bridgeId == mesh.getNodeId()) ? " (ME)" : "");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Show recommended bridge for next message
|
|
43
|
+
uint32_t recommended = mesh.getRecommendedBridge();
|
|
44
|
+
Serial.printf("Recommended Bridge: %u\n", recommended);
|
|
45
|
+
|
|
46
|
+
if (recommended == mesh.getNodeId()) {
|
|
47
|
+
Serial.println("⚠️ I AM THE ACTIVE BRIDGE (primary likely failed!)");
|
|
48
|
+
} else {
|
|
49
|
+
Serial.println("✓ Standby mode - primary bridge is active");
|
|
50
|
+
}
|
|
51
|
+
Serial.println("=============================\n");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
void receivedCallback(uint32_t from, String& msg) {
|
|
55
|
+
Serial.printf("Received from %u: %s\n", from, msg.c_str());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
void newConnectionCallback(uint32_t nodeId) {
|
|
59
|
+
Serial.printf("New Connection, nodeId = %u\n", nodeId);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
void changedConnectionCallback() {
|
|
63
|
+
Serial.printf("Changed connections. Node count: %d\n", mesh.getNodeList().size());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void bridgeStatusCallback(uint32_t bridgeNodeId, bool hasInternet) {
|
|
67
|
+
if (hasInternet) {
|
|
68
|
+
Serial.printf("✓ Bridge %u: Internet connected\n", bridgeNodeId);
|
|
69
|
+
} else {
|
|
70
|
+
Serial.printf("⚠️ Bridge %u: Internet OFFLINE\n", bridgeNodeId);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
void setup() {
|
|
75
|
+
Serial.begin(115200);
|
|
76
|
+
delay(2000);
|
|
77
|
+
|
|
78
|
+
Serial.println("\n\n=== Multi-Bridge: SECONDARY BRIDGE ===\n");
|
|
79
|
+
|
|
80
|
+
// Initialize mesh as secondary bridge with priority 5
|
|
81
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
82
|
+
|
|
83
|
+
// Enable multi-bridge coordination mode
|
|
84
|
+
mesh.enableMultiBridge(true);
|
|
85
|
+
|
|
86
|
+
// Set bridge selection strategy (PRIORITY_BASED is default)
|
|
87
|
+
mesh.setBridgeSelectionStrategy(painlessMesh::PRIORITY_BASED);
|
|
88
|
+
|
|
89
|
+
// Initialize as bridge with priority 5 (secondary)
|
|
90
|
+
mesh.initAsBridge(MESH_PREFIX, MESH_PASSWORD,
|
|
91
|
+
ROUTER_SSID, ROUTER_PASSWORD,
|
|
92
|
+
&userScheduler, MESH_PORT, 5); // Priority 5 = Secondary
|
|
93
|
+
|
|
94
|
+
mesh.onReceive(&receivedCallback);
|
|
95
|
+
mesh.onNewConnection(&newConnectionCallback);
|
|
96
|
+
mesh.onChangedConnections(&changedConnectionCallback);
|
|
97
|
+
mesh.onBridgeStatusChanged(&bridgeStatusCallback);
|
|
98
|
+
|
|
99
|
+
// Add status reporting task
|
|
100
|
+
userScheduler.addTask(taskBridgeStatus);
|
|
101
|
+
taskBridgeStatus.enable();
|
|
102
|
+
|
|
103
|
+
Serial.println("\n=== Secondary Bridge Ready ===");
|
|
104
|
+
Serial.println("This node is the SECONDARY bridge (Priority 5)");
|
|
105
|
+
Serial.println("It operates in hot standby mode");
|
|
106
|
+
Serial.println("Will take over if primary bridge fails\n");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
void loop() {
|
|
110
|
+
mesh.update();
|
|
111
|
+
}
|