@alteriom/painlessmesh 1.7.9 → 1.8.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/CHANGELOG.md +94 -2
- package/README.md +108 -1
- 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/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/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 +572 -0
- package/src/painlessMeshSTA.cpp +63 -0
- package/src/painlessMeshSTA.h +3 -0
- package/src/painlessmesh/mesh.hpp +1127 -4
- package/src/painlessmesh/rtc.hpp +203 -0
package/examples/basic/basic.ino
CHANGED
|
@@ -48,9 +48,13 @@ void setup() {
|
|
|
48
48
|
Serial.begin(115200);
|
|
49
49
|
|
|
50
50
|
//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
|
|
51
|
-
mesh.setDebugMsgTypes( ERROR | STARTUP ); // set before init() so that you can see startup messages
|
|
51
|
+
mesh.setDebugMsgTypes( ERROR | STARTUP | CONNECTION ); // set before init() so that you can see startup messages
|
|
52
52
|
|
|
53
|
-
mesh
|
|
53
|
+
// Initialize mesh network with auto channel detection
|
|
54
|
+
// Using channel=0 tells the node to scan all channels and auto-detect the mesh
|
|
55
|
+
// This is useful when you have a bridge node that sets the channel dynamically
|
|
56
|
+
mesh.init( MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 0 );
|
|
57
|
+
|
|
54
58
|
mesh.onReceive(&receivedCallback);
|
|
55
59
|
mesh.onNewConnection(&newConnectionCallback);
|
|
56
60
|
mesh.onChangedConnections(&changedConnectionCallback);
|
|
@@ -1,47 +1,68 @@
|
|
|
1
1
|
//************************************************************
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
2
|
+
// Bridge Node Example - Automatic Channel Detection
|
|
3
|
+
//
|
|
4
|
+
// This example demonstrates the new bridge-centric architecture that
|
|
5
|
+
// automatically detects the router's WiFi channel and configures the
|
|
6
|
+
// mesh network accordingly.
|
|
7
|
+
//
|
|
8
|
+
// Features:
|
|
9
|
+
// - Connects to router FIRST and auto-detects its channel
|
|
10
|
+
// - Creates mesh network on the same channel as router
|
|
11
|
+
// - No manual channel configuration required
|
|
12
|
+
// - Automatically sets itself as root node
|
|
13
|
+
// - Broadcasts bridge status to mesh (Type 610 - BRIDGE_STATUS)
|
|
14
|
+
// - Reports Internet connectivity status
|
|
15
|
+
// - Updates every 30 seconds by default
|
|
16
|
+
// - Enables nodes to implement failover and queueing logic
|
|
17
|
+
//
|
|
18
|
+
// For more details, see BRIDGE_TO_INTERNET.md
|
|
6
19
|
//************************************************************
|
|
7
20
|
#include "painlessMesh.h"
|
|
8
21
|
|
|
22
|
+
// Mesh network configuration
|
|
9
23
|
#define MESH_PREFIX "whateverYouLike"
|
|
10
24
|
#define MESH_PASSWORD "somethingSneaky"
|
|
11
25
|
#define MESH_PORT 5555
|
|
12
26
|
|
|
13
|
-
|
|
14
|
-
#define
|
|
15
|
-
#define
|
|
16
|
-
uint8_t station_ip[4] = {192, 168, 1, 3}; // IP of the server
|
|
27
|
+
// Router credentials
|
|
28
|
+
#define ROUTER_SSID "MSYSSID"
|
|
29
|
+
#define ROUTER_PASSWORD "SSIDPASSWORD"
|
|
17
30
|
|
|
18
31
|
// prototypes
|
|
19
32
|
void receivedCallback(uint32_t from, String &msg);
|
|
20
33
|
|
|
34
|
+
Scheduler userScheduler;
|
|
21
35
|
painlessMesh mesh;
|
|
22
36
|
|
|
23
37
|
void setup() {
|
|
24
38
|
Serial.begin(115200);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
|
|
40
|
+
// Set debug message types before init() to see startup messages
|
|
41
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
42
|
+
|
|
43
|
+
// NEW: Single call to initialize as bridge with auto channel detection
|
|
44
|
+
// This will:
|
|
45
|
+
// 1. Connect to router and detect its channel
|
|
46
|
+
// 2. Initialize mesh on the detected channel
|
|
47
|
+
// 3. Set this node as root
|
|
48
|
+
// 4. Maintain router connection
|
|
49
|
+
// 5. Start broadcasting bridge status (Type 610) every 30 seconds
|
|
50
|
+
mesh.initAsBridge(MESH_PREFIX, MESH_PASSWORD,
|
|
51
|
+
ROUTER_SSID, ROUTER_PASSWORD,
|
|
52
|
+
&userScheduler, MESH_PORT);
|
|
53
|
+
|
|
54
|
+
// Optional: Configure bridge status broadcasting
|
|
55
|
+
// mesh.setBridgeStatusInterval(60000); // Change to 60 seconds
|
|
56
|
+
// mesh.enableBridgeStatusBroadcast(false); // Disable if not needed
|
|
28
57
|
|
|
29
|
-
// Initialize mesh network in AP+STA mode on channel 1
|
|
30
|
-
// stationManual() will automatically handle channel switching if needed
|
|
31
|
-
mesh.init(MESH_PREFIX, MESH_PASSWORD, MESH_PORT, WIFI_AP_STA, 1);
|
|
32
58
|
// Setup over the air update support
|
|
33
59
|
mesh.initOTAReceive("bridge");
|
|
34
60
|
|
|
35
|
-
|
|
36
|
-
// Bridge node, should (in most cases) be a root node. See [the
|
|
37
|
-
// wiki](https://gitlab.com/painlessMesh/painlessMesh/wikis/Possible-challenges-in-mesh-formation)
|
|
38
|
-
// for some background
|
|
39
|
-
mesh.setRoot(true);
|
|
40
|
-
// This node and all other nodes should ideally know the mesh contains a root,
|
|
41
|
-
// so call this on all nodes
|
|
42
|
-
mesh.setContainsRoot(true);
|
|
43
|
-
|
|
61
|
+
// Set up message callback
|
|
44
62
|
mesh.onReceive(&receivedCallback);
|
|
63
|
+
|
|
64
|
+
Serial.println("Bridge node initialized and ready!");
|
|
65
|
+
Serial.println("Broadcasting bridge status to mesh every 30 seconds");
|
|
45
66
|
}
|
|
46
67
|
|
|
47
68
|
void loop() { mesh.update(); }
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge Health Monitoring Example
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates the new bridge health metrics API for monitoring
|
|
5
|
+
* bridge connectivity, signal quality, traffic, and performance.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Periodic metrics collection and logging
|
|
9
|
+
* - MQTT integration for publishing metrics
|
|
10
|
+
* - Prometheus-style metrics export
|
|
11
|
+
* - Manual metrics reset and JSON export
|
|
12
|
+
*
|
|
13
|
+
* Hardware: ESP32 or ESP8266
|
|
14
|
+
*
|
|
15
|
+
* Based on painlessMesh v1.7.7+ bridge health monitoring feature
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include "painlessMesh.h"
|
|
19
|
+
|
|
20
|
+
// Mesh network configuration
|
|
21
|
+
#define MESH_PREFIX "BridgeMesh"
|
|
22
|
+
#define MESH_PASSWORD "somethingSneaky"
|
|
23
|
+
#define MESH_PORT 5555
|
|
24
|
+
|
|
25
|
+
// Bridge node configuration
|
|
26
|
+
#define STATION_SSID "YourWiFiSSID"
|
|
27
|
+
#define STATION_PASSWORD "YourWiFiPassword"
|
|
28
|
+
|
|
29
|
+
// Metrics reporting interval (60 seconds)
|
|
30
|
+
#define METRICS_INTERVAL 60000
|
|
31
|
+
|
|
32
|
+
Scheduler userScheduler;
|
|
33
|
+
painlessMesh mesh;
|
|
34
|
+
|
|
35
|
+
// MQTT client (if using MQTT integration)
|
|
36
|
+
// #include <PubSubClient.h>
|
|
37
|
+
// WiFiClient espClient;
|
|
38
|
+
// PubSubClient mqttClient(espClient);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Metrics callback - called periodically with current metrics
|
|
42
|
+
* This is where you'd publish to MQTT, send to logging service, etc.
|
|
43
|
+
*/
|
|
44
|
+
void metricsCallback(painlessmesh::BridgeHealthMetrics metrics) {
|
|
45
|
+
Serial.println("\n========== Bridge Health Metrics ==========");
|
|
46
|
+
|
|
47
|
+
// Connectivity
|
|
48
|
+
Serial.println("Connectivity:");
|
|
49
|
+
Serial.printf(" Uptime: %u seconds\n", metrics.uptimeSeconds);
|
|
50
|
+
Serial.printf(" Internet Uptime: %u seconds\n", metrics.internetUptimeSeconds);
|
|
51
|
+
Serial.printf(" Total Disconnects: %u\n", metrics.totalDisconnects);
|
|
52
|
+
|
|
53
|
+
// Signal Quality
|
|
54
|
+
Serial.println("\nSignal Quality:");
|
|
55
|
+
Serial.printf(" Current RSSI: %d dBm\n", metrics.currentRSSI);
|
|
56
|
+
Serial.printf(" Average RSSI: %d dBm\n", metrics.avgRSSI);
|
|
57
|
+
Serial.printf(" Min RSSI: %d dBm\n", metrics.minRSSI);
|
|
58
|
+
Serial.printf(" Max RSSI: %d dBm\n", metrics.maxRSSI);
|
|
59
|
+
|
|
60
|
+
// Traffic
|
|
61
|
+
Serial.println("\nTraffic:");
|
|
62
|
+
Serial.printf(" Bytes RX: %llu\n", metrics.bytesRx);
|
|
63
|
+
Serial.printf(" Bytes TX: %llu\n", metrics.bytesTx);
|
|
64
|
+
Serial.printf(" Messages RX: %u\n", metrics.messagesRx);
|
|
65
|
+
Serial.printf(" Messages TX: %u\n", metrics.messagesTx);
|
|
66
|
+
Serial.printf(" Messages Dropped: %u\n", metrics.messagesDropped);
|
|
67
|
+
|
|
68
|
+
// Performance
|
|
69
|
+
Serial.println("\nPerformance:");
|
|
70
|
+
Serial.printf(" Avg Latency: %u ms\n", metrics.avgLatencyMs);
|
|
71
|
+
Serial.printf(" Packet Loss: %u%%\n", metrics.packetLossPercent);
|
|
72
|
+
Serial.printf(" Mesh Nodes: %u\n", metrics.meshNodeCount);
|
|
73
|
+
|
|
74
|
+
Serial.println("==========================================\n");
|
|
75
|
+
|
|
76
|
+
// MQTT Integration Example
|
|
77
|
+
// Uncomment if using MQTT
|
|
78
|
+
/*
|
|
79
|
+
if (mqttClient.connected()) {
|
|
80
|
+
String json = mesh.getHealthMetricsJSON();
|
|
81
|
+
mqttClient.publish("bridge/metrics", json.c_str());
|
|
82
|
+
Serial.println("Metrics published to MQTT");
|
|
83
|
+
}
|
|
84
|
+
*/
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Export metrics in Prometheus format
|
|
89
|
+
* Call this from a web server endpoint for Prometheus scraping
|
|
90
|
+
*/
|
|
91
|
+
String exportPrometheus() {
|
|
92
|
+
auto metrics = mesh.getBridgeHealthMetrics();
|
|
93
|
+
|
|
94
|
+
String output = "";
|
|
95
|
+
|
|
96
|
+
// Connectivity metrics
|
|
97
|
+
output += "# HELP bridge_uptime_seconds Bridge uptime in seconds\n";
|
|
98
|
+
output += "# TYPE bridge_uptime_seconds counter\n";
|
|
99
|
+
output += "bridge_uptime_seconds " + String(metrics.uptimeSeconds) + "\n";
|
|
100
|
+
|
|
101
|
+
output += "# HELP bridge_internet_uptime_seconds Internet connectivity uptime\n";
|
|
102
|
+
output += "# TYPE bridge_internet_uptime_seconds counter\n";
|
|
103
|
+
output += "bridge_internet_uptime_seconds " + String(metrics.internetUptimeSeconds) + "\n";
|
|
104
|
+
|
|
105
|
+
output += "# HELP bridge_disconnects_total Total number of disconnections\n";
|
|
106
|
+
output += "# TYPE bridge_disconnects_total counter\n";
|
|
107
|
+
output += "bridge_disconnects_total " + String(metrics.totalDisconnects) + "\n";
|
|
108
|
+
|
|
109
|
+
// Signal quality metrics
|
|
110
|
+
output += "# HELP bridge_rssi_dbm WiFi signal strength in dBm\n";
|
|
111
|
+
output += "# TYPE bridge_rssi_dbm gauge\n";
|
|
112
|
+
output += "bridge_rssi_dbm{type=\"current\"} " + String(metrics.currentRSSI) + "\n";
|
|
113
|
+
output += "bridge_rssi_dbm{type=\"average\"} " + String(metrics.avgRSSI) + "\n";
|
|
114
|
+
output += "bridge_rssi_dbm{type=\"min\"} " + String(metrics.minRSSI) + "\n";
|
|
115
|
+
output += "bridge_rssi_dbm{type=\"max\"} " + String(metrics.maxRSSI) + "\n";
|
|
116
|
+
|
|
117
|
+
// Traffic metrics
|
|
118
|
+
output += "# HELP bridge_bytes_total Total bytes transferred\n";
|
|
119
|
+
output += "# TYPE bridge_bytes_total counter\n";
|
|
120
|
+
output += "bridge_bytes_total{direction=\"rx\"} " + String((unsigned long)metrics.bytesRx) + "\n";
|
|
121
|
+
output += "bridge_bytes_total{direction=\"tx\"} " + String((unsigned long)metrics.bytesTx) + "\n";
|
|
122
|
+
|
|
123
|
+
output += "# HELP bridge_messages_total Total messages processed\n";
|
|
124
|
+
output += "# TYPE bridge_messages_total counter\n";
|
|
125
|
+
output += "bridge_messages_total{direction=\"rx\"} " + String(metrics.messagesRx) + "\n";
|
|
126
|
+
output += "bridge_messages_total{direction=\"tx\"} " + String(metrics.messagesTx) + "\n";
|
|
127
|
+
output += "bridge_messages_total{status=\"dropped\"} " + String(metrics.messagesDropped) + "\n";
|
|
128
|
+
|
|
129
|
+
// Performance metrics
|
|
130
|
+
output += "# HELP bridge_latency_ms Average message latency in milliseconds\n";
|
|
131
|
+
output += "# TYPE bridge_latency_ms gauge\n";
|
|
132
|
+
output += "bridge_latency_ms " + String(metrics.avgLatencyMs) + "\n";
|
|
133
|
+
|
|
134
|
+
output += "# HELP bridge_packet_loss_percent Packet loss percentage\n";
|
|
135
|
+
output += "# TYPE bridge_packet_loss_percent gauge\n";
|
|
136
|
+
output += "bridge_packet_loss_percent " + String(metrics.packetLossPercent) + "\n";
|
|
137
|
+
|
|
138
|
+
output += "# HELP bridge_mesh_nodes Total nodes in mesh network\n";
|
|
139
|
+
output += "# TYPE bridge_mesh_nodes gauge\n";
|
|
140
|
+
output += "bridge_mesh_nodes " + String(metrics.meshNodeCount) + "\n";
|
|
141
|
+
|
|
142
|
+
return output;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Manual metrics check task
|
|
147
|
+
* Demonstrates how to manually get metrics on demand
|
|
148
|
+
*/
|
|
149
|
+
Task taskManualMetricsCheck(10000, TASK_FOREVER, [](){
|
|
150
|
+
// Get metrics JSON for logging or transmission
|
|
151
|
+
String json = mesh.getHealthMetricsJSON();
|
|
152
|
+
Serial.println("JSON Metrics: " + json);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
void setup() {
|
|
156
|
+
Serial.begin(115200);
|
|
157
|
+
|
|
158
|
+
// Mesh initialization
|
|
159
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
160
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
|
|
161
|
+
|
|
162
|
+
// Configure as a bridge (root) node
|
|
163
|
+
mesh.setRoot(true);
|
|
164
|
+
mesh.setContainsRoot(true);
|
|
165
|
+
|
|
166
|
+
// Connect to WiFi station for Internet access
|
|
167
|
+
mesh.stationManual(STATION_SSID, STATION_PASSWORD);
|
|
168
|
+
mesh.setHostname("BridgeNode");
|
|
169
|
+
|
|
170
|
+
// Set up periodic health metrics callback (every 60 seconds)
|
|
171
|
+
mesh.onHealthMetricsUpdate(metricsCallback, METRICS_INTERVAL);
|
|
172
|
+
|
|
173
|
+
// Optional: Add manual metrics check task
|
|
174
|
+
// userScheduler.addTask(taskManualMetricsCheck);
|
|
175
|
+
// taskManualMetricsCheck.enable();
|
|
176
|
+
|
|
177
|
+
Serial.println("Bridge with health monitoring started");
|
|
178
|
+
Serial.println("Metrics will be reported every 60 seconds");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
void loop() {
|
|
182
|
+
mesh.update();
|
|
183
|
+
|
|
184
|
+
// If you have a web server for Prometheus endpoint:
|
|
185
|
+
// server.on("/metrics", HTTP_GET, [](){
|
|
186
|
+
// server.send(200, "text/plain", exportPrometheus());
|
|
187
|
+
// });
|
|
188
|
+
}
|