@alteriom/painlessmesh 1.6.1 → 1.7.2
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 +380 -143
- package/LICENSE +674 -674
- package/README.md +477 -434
- package/RELEASE_GUIDE.md +504 -418
- package/docs/DOCUMENTATION_MIGRATION_PLAN.md +175 -175
- package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +1062 -0
- package/docs/MESH_TOPOLOGY_GUIDE.md +992 -0
- package/docs/MESH_TOPOLOGY_PROGRESS.md +422 -0
- package/docs/MQTT_BRIDGE_COMMANDS.md +894 -0
- package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +324 -0
- package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +576 -0
- package/docs/MQTT_SCHEMA_COMPLIANCE.md +285 -0
- package/docs/MQTT_SCHEMA_PROPOSALS.md +446 -0
- package/docs/MQTT_SCHEMA_REVIEW.md +690 -0
- package/docs/OTA_COMMANDS_REFERENCE.md +554 -0
- package/docs/PHASE1_GUIDE.md +349 -0
- package/docs/PHASE2_GUIDE.md +543 -0
- package/docs/README.md +77 -70
- package/docs/SCHEMA_VALIDATION_CHECKLIST.md +222 -0
- package/docs/alteriom/overview.md +507 -507
- package/docs/api/core-api.md +606 -606
- package/docs/architecture/mesh-architecture.md +378 -378
- package/docs/architecture/plugin-system.md +516 -516
- package/docs/getting-started/first-mesh.md +409 -409
- package/docs/getting-started/installation.md +274 -274
- package/docs/getting-started/quickstart.md +157 -157
- package/docs/improvements/FEATURE_PROPOSALS.md +337 -0
- package/docs/improvements/PHASE1_IMPLEMENTATION.md +325 -0
- package/docs/improvements/PHASE2_IMPLEMENTATION.md +567 -0
- package/docs/improvements/README.md +86 -68
- package/docs/improvements/ota-and-status-enhancements.md +911 -0
- package/docs/improvements/ota-status-architecture-diagrams.md +658 -0
- package/docs/improvements/ota-status-quick-reference.md +284 -0
- package/docs/platformio-publishing.md +255 -0
- package/docs/platformio-setup-summary.md +121 -0
- package/docs/troubleshooting/common-issues.md +520 -520
- package/docs/troubleshooting/faq.md +472 -472
- package/docs/tutorials/basic-examples.md +717 -717
- package/docs/wiki/API-Reference.md +245 -245
- package/docs/wiki/Complete-Documentation.md +122 -122
- package/examples/alteriom/README.md +139 -81
- package/examples/alteriom/alteriom.ino +186 -185
- package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
- package/examples/alteriom/platformio.ini +24 -24
- package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
- package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
- package/examples/alteriomImproved/platformio.ini +25 -0
- package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomPhase1/phase1_features.ino +242 -0
- package/examples/alteriomPhase1/platformio.ini +25 -0
- package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomPhase2/phase2_features.ino +186 -0
- package/examples/alteriomPhase2/platformio.ini +25 -0
- package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomSensorNode/platformio.ini +25 -0
- package/examples/basic/basic.ino +66 -66
- package/examples/basic/platformio.ini +25 -25
- package/examples/bridge/bridge.ino +51 -51
- package/examples/bridge/mesh_event_publisher.hpp +253 -0
- package/examples/bridge/mesh_topology_reporter.hpp +303 -0
- package/examples/bridge/mqtt_command_bridge.hpp +459 -0
- package/examples/bridge/mqtt_status_bridge.hpp +519 -0
- package/examples/bridge/platformio.ini +25 -25
- package/examples/echoNode/echoNode.ino +33 -33
- package/examples/echoNode/platformio.ini +25 -25
- package/examples/logClient/logClient.ino +109 -109
- package/examples/logClient/platformio.ini +25 -25
- package/examples/logServer/logServer.ino +81 -81
- package/examples/logServer/platformio.ini +25 -25
- package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
- package/examples/meshCommandNode/meshCommandNode.ino +263 -0
- package/examples/meshCommandNode/platformio.ini +25 -0
- package/examples/mqttBridge/mqttBridge.ino +118 -118
- package/examples/mqttBridge/platformio.ini +26 -26
- package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
- package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
- package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
- package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
- package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
- package/examples/mqttCommandBridge/platformio.ini +26 -0
- package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
- package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
- package/examples/mqttStatusBridge/platformio.ini +26 -0
- package/examples/mqttTopologyTest/README.md +467 -0
- package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
- package/examples/mqttTopologyTest/platformio.ini +26 -0
- package/examples/namedMesh/namedMesh.ino +97 -97
- package/examples/namedMesh/platformio.ini +25 -25
- package/examples/otaReceiver/otaReceiver.ino +79 -79
- package/examples/otaReceiver/platformio.ini +25 -25
- package/examples/otaSender/otaSender.ino +160 -151
- package/examples/otaSender/platformio.ini +25 -25
- package/examples/startHere/platformio.ini +25 -25
- package/examples/startHere/startHere.ino +159 -159
- package/examples/webServer/platformio.ini +27 -27
- package/examples/webServer/webServer.ino +89 -89
- package/keywords.txt +48 -48
- package/library.json +55 -34
- package/library.properties +10 -10
- package/package.json +86 -78
- package/src/AlteriomPainlessMesh.h +97 -97
- package/src/arduino/wifi.hpp +365 -365
- package/src/boost/asynctcp.hpp +279 -279
- package/src/painlessMesh.h +70 -70
- package/src/painlessMeshSTA.cpp +236 -236
- package/src/painlessMeshSTA.h +58 -58
- package/src/painlessTaskOptions.h +4 -4
- package/src/painlessmesh/base64.hpp +111 -111
- package/src/painlessmesh/buffer.hpp +229 -229
- package/src/painlessmesh/callback.hpp +91 -91
- package/src/painlessmesh/configuration.hpp +77 -77
- package/src/painlessmesh/connection.hpp +192 -192
- package/src/painlessmesh/layout.hpp +188 -188
- package/src/painlessmesh/logger.hpp +158 -158
- package/src/painlessmesh/memory.hpp +119 -119
- package/src/painlessmesh/mesh.hpp +761 -560
- package/src/painlessmesh/metrics.hpp +322 -322
- package/src/painlessmesh/ntp.hpp +263 -263
- package/src/painlessmesh/ota.hpp +582 -553
- package/src/painlessmesh/plugin.hpp +188 -188
- package/src/painlessmesh/protocol.hpp +813 -813
- package/src/painlessmesh/router.hpp +322 -322
- package/src/painlessmesh/tcp.hpp +71 -71
- package/src/painlessmesh/validation.hpp +238 -238
- package/src/plugin/performance.hpp +214 -214
- package/src/plugin/remote.hpp +64 -64
- package/src/scheduler.cpp +10 -10
- package/src/wifi.cpp +2 -2
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[platformio]
|
|
2
|
+
src_dir = .
|
|
3
|
+
|
|
4
|
+
[env]
|
|
5
|
+
lib_deps =
|
|
6
|
+
bblanchon/ArduinoJson
|
|
7
|
+
arkhipenko/TaskScheduler
|
|
8
|
+
knolleary/PubSubClient
|
|
9
|
+
|
|
10
|
+
[env:esp8266]
|
|
11
|
+
platform = espressif8266
|
|
12
|
+
board = nodemcuv2
|
|
13
|
+
framework = arduino
|
|
14
|
+
lib_extra_dirs = ../../
|
|
15
|
+
lib_deps =
|
|
16
|
+
${env.lib_deps} ; Inherit common dependencies
|
|
17
|
+
esp32async/ESPAsyncTCP@^2.0.0 ; Only for ESP8266
|
|
18
|
+
|
|
19
|
+
[env:esp32]
|
|
20
|
+
platform = espressif32
|
|
21
|
+
board = esp32dev
|
|
22
|
+
framework = arduino
|
|
23
|
+
lib_extra_dirs = ../../
|
|
24
|
+
lib_deps =
|
|
25
|
+
${env.lib_deps} ; Inherit common dependencies
|
|
26
|
+
esp32async/AsyncTCP
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
//************************************************************
|
|
2
|
+
// Phase 2: MQTT Status Bridge Example
|
|
3
|
+
//
|
|
4
|
+
// This example demonstrates the MQTT Status Bridge feature,
|
|
5
|
+
// which publishes comprehensive mesh status to MQTT topics
|
|
6
|
+
// for professional monitoring with tools like:
|
|
7
|
+
// - Grafana
|
|
8
|
+
// - InfluxDB
|
|
9
|
+
// - Prometheus
|
|
10
|
+
// - Home Assistant
|
|
11
|
+
// - Node-RED
|
|
12
|
+
//
|
|
13
|
+
// MQTT Topics Published:
|
|
14
|
+
// - mesh/status/nodes - List of all nodes in mesh
|
|
15
|
+
// - mesh/status/topology - Complete mesh topology JSON
|
|
16
|
+
// - mesh/status/metrics - Performance metrics
|
|
17
|
+
// - mesh/status/alerts - Active alerts
|
|
18
|
+
// - mesh/status/node/{id} - Per-node detailed status (optional)
|
|
19
|
+
//
|
|
20
|
+
// Requirements:
|
|
21
|
+
// - ESP32 or ESP8266
|
|
22
|
+
// - WiFi connection to external network (for MQTT broker)
|
|
23
|
+
// - MQTT broker (e.g., Mosquitto, HiveMQ, AWS IoT)
|
|
24
|
+
//************************************************************
|
|
25
|
+
|
|
26
|
+
#include <Arduino.h>
|
|
27
|
+
#include <painlessMesh.h>
|
|
28
|
+
#include <PubSubClient.h>
|
|
29
|
+
#include <WiFiClient.h>
|
|
30
|
+
#include "mqtt_status_bridge.hpp"
|
|
31
|
+
|
|
32
|
+
// Mesh configuration
|
|
33
|
+
#define MESH_PREFIX "AlteriomMesh"
|
|
34
|
+
#define MESH_PASSWORD "somethingSneaky"
|
|
35
|
+
#define MESH_PORT 5555
|
|
36
|
+
|
|
37
|
+
// External WiFi configuration (for MQTT connection)
|
|
38
|
+
#define STATION_SSID "YourAP_SSID"
|
|
39
|
+
#define STATION_PASSWORD "YourAP_PWD"
|
|
40
|
+
|
|
41
|
+
// MQTT broker configuration
|
|
42
|
+
#define MQTT_BROKER_IP "192.168.1.100" // Change to your MQTT broker IP
|
|
43
|
+
#define MQTT_BROKER_PORT 1883
|
|
44
|
+
#define MQTT_CLIENT_ID "painlessMesh_StatusBridge"
|
|
45
|
+
|
|
46
|
+
#define HOSTNAME "MQTT_Status_Bridge"
|
|
47
|
+
|
|
48
|
+
// Prototypes
|
|
49
|
+
void receivedCallback(const uint32_t &from, const String &msg);
|
|
50
|
+
void mqttCallback(char* topic, byte* payload, unsigned int length);
|
|
51
|
+
IPAddress getlocalIP();
|
|
52
|
+
|
|
53
|
+
// Global objects
|
|
54
|
+
IPAddress myIP(0, 0, 0, 0);
|
|
55
|
+
IPAddress mqttBroker(192, 168, 1, 100); // Change to your MQTT broker IP
|
|
56
|
+
|
|
57
|
+
Scheduler userScheduler;
|
|
58
|
+
painlessMesh mesh;
|
|
59
|
+
WiFiClient wifiClient;
|
|
60
|
+
PubSubClient mqttClient(mqttBroker, MQTT_BROKER_PORT, mqttCallback, wifiClient);
|
|
61
|
+
|
|
62
|
+
// Phase 2: MQTT Status Bridge instance
|
|
63
|
+
MqttStatusBridge* statusBridge = nullptr;
|
|
64
|
+
|
|
65
|
+
void setup() {
|
|
66
|
+
Serial.begin(115200);
|
|
67
|
+
Serial.println("\n\n=== Phase 2: MQTT Status Bridge Example ===\n");
|
|
68
|
+
|
|
69
|
+
// Initialize mesh
|
|
70
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
71
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 6);
|
|
72
|
+
mesh.onReceive(&receivedCallback);
|
|
73
|
+
|
|
74
|
+
// Connect to external WiFi for MQTT
|
|
75
|
+
mesh.stationManual(STATION_SSID, STATION_PASSWORD);
|
|
76
|
+
mesh.setHostname(HOSTNAME);
|
|
77
|
+
|
|
78
|
+
// Bridge node should be root
|
|
79
|
+
mesh.setRoot(true);
|
|
80
|
+
mesh.setContainsRoot(true);
|
|
81
|
+
|
|
82
|
+
Serial.println("Mesh initialized");
|
|
83
|
+
Serial.println("Waiting for WiFi and MQTT connection...");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
void loop() {
|
|
87
|
+
mesh.update();
|
|
88
|
+
mqttClient.loop();
|
|
89
|
+
|
|
90
|
+
// Check for WiFi connection and connect to MQTT
|
|
91
|
+
if (myIP != getlocalIP()) {
|
|
92
|
+
myIP = getlocalIP();
|
|
93
|
+
Serial.println("WiFi connected!");
|
|
94
|
+
Serial.print("IP address: ");
|
|
95
|
+
Serial.println(myIP.toString());
|
|
96
|
+
|
|
97
|
+
// Connect to MQTT broker
|
|
98
|
+
if (mqttClient.connect(MQTT_CLIENT_ID)) {
|
|
99
|
+
Serial.println("MQTT connected!");
|
|
100
|
+
Serial.print("Broker: ");
|
|
101
|
+
Serial.print(mqttBroker.toString());
|
|
102
|
+
Serial.print(":");
|
|
103
|
+
Serial.println(MQTT_BROKER_PORT);
|
|
104
|
+
|
|
105
|
+
// Subscribe to mesh command topics (optional)
|
|
106
|
+
mqttClient.subscribe("mesh/command/#");
|
|
107
|
+
mqttClient.publish("mesh/status/bridge", "Bridge online!");
|
|
108
|
+
|
|
109
|
+
// Phase 2: Initialize and start MQTT Status Bridge
|
|
110
|
+
if (statusBridge == nullptr) {
|
|
111
|
+
statusBridge = new MqttStatusBridge(mesh, mqttClient, userScheduler);
|
|
112
|
+
|
|
113
|
+
// Configure the bridge
|
|
114
|
+
statusBridge->setPublishInterval(30000); // Publish every 30 seconds
|
|
115
|
+
statusBridge->setTopicPrefix("mesh/status/");
|
|
116
|
+
|
|
117
|
+
// Enable features (all enabled by default)
|
|
118
|
+
statusBridge->enableTopology(true); // Publish mesh topology
|
|
119
|
+
statusBridge->enableMetrics(true); // Publish performance metrics
|
|
120
|
+
statusBridge->enableAlerts(true); // Publish active alerts
|
|
121
|
+
statusBridge->enablePerNode(false); // Per-node status (can be expensive)
|
|
122
|
+
|
|
123
|
+
// Start publishing
|
|
124
|
+
statusBridge->begin();
|
|
125
|
+
|
|
126
|
+
Serial.println("\n=== MQTT Status Bridge Configured ===");
|
|
127
|
+
Serial.println("Publishing to topics:");
|
|
128
|
+
Serial.println(" - mesh/status/nodes");
|
|
129
|
+
Serial.println(" - mesh/status/topology");
|
|
130
|
+
Serial.println(" - mesh/status/metrics");
|
|
131
|
+
Serial.println(" - mesh/status/alerts");
|
|
132
|
+
Serial.println("Publish interval: 30 seconds\n");
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
Serial.print("MQTT connection failed, rc=");
|
|
136
|
+
Serial.println(mqttClient.state());
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Reconnect to MQTT if connection is lost
|
|
141
|
+
static unsigned long lastReconnectAttempt = 0;
|
|
142
|
+
if (!mqttClient.connected() && myIP != IPAddress(0, 0, 0, 0)) {
|
|
143
|
+
unsigned long now = millis();
|
|
144
|
+
if (now - lastReconnectAttempt > 5000) {
|
|
145
|
+
lastReconnectAttempt = now;
|
|
146
|
+
Serial.println("Attempting MQTT reconnection...");
|
|
147
|
+
if (mqttClient.connect(MQTT_CLIENT_ID)) {
|
|
148
|
+
Serial.println("MQTT reconnected!");
|
|
149
|
+
mqttClient.subscribe("mesh/command/#");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
void receivedCallback(const uint32_t &from, const String &msg) {
|
|
156
|
+
Serial.printf("Received from %u: %s\n", from, msg.c_str());
|
|
157
|
+
|
|
158
|
+
// Forward mesh messages to MQTT
|
|
159
|
+
String topic = "mesh/from/" + String(from);
|
|
160
|
+
if (mqttClient.connected()) {
|
|
161
|
+
mqttClient.publish(topic.c_str(), msg.c_str());
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
void mqttCallback(char* topic, uint8_t* payload, unsigned int length) {
|
|
166
|
+
// Parse payload
|
|
167
|
+
char* cleanPayload = (char*)malloc(length + 1);
|
|
168
|
+
memcpy(cleanPayload, payload, length);
|
|
169
|
+
cleanPayload[length] = '\0';
|
|
170
|
+
String msg = String(cleanPayload);
|
|
171
|
+
free(cleanPayload);
|
|
172
|
+
|
|
173
|
+
Serial.printf("MQTT received on %s: %s\n", topic, msg.c_str());
|
|
174
|
+
|
|
175
|
+
String topicStr = String(topic);
|
|
176
|
+
|
|
177
|
+
// Handle mesh commands
|
|
178
|
+
if (topicStr.startsWith("mesh/command/")) {
|
|
179
|
+
String command = topicStr.substring(13); // Remove "mesh/command/"
|
|
180
|
+
|
|
181
|
+
if (command == "getNodes") {
|
|
182
|
+
// Get node list
|
|
183
|
+
auto nodes = mesh.getNodeList(true);
|
|
184
|
+
String nodeList = "{\"nodes\":[";
|
|
185
|
+
bool firstNode = true;
|
|
186
|
+
for (auto nodeId : nodes) {
|
|
187
|
+
if (!firstNode) nodeList += ",";
|
|
188
|
+
firstNode = false;
|
|
189
|
+
nodeList += String(nodeId);
|
|
190
|
+
}
|
|
191
|
+
nodeList += "]}";
|
|
192
|
+
mqttClient.publish("mesh/response/nodes", nodeList.c_str());
|
|
193
|
+
}
|
|
194
|
+
else if (command == "getTopology") {
|
|
195
|
+
// Get mesh topology
|
|
196
|
+
String topology = mesh.subConnectionJson(false);
|
|
197
|
+
mqttClient.publish("mesh/response/topology", topology.c_str());
|
|
198
|
+
}
|
|
199
|
+
else if (command == "publishNow") {
|
|
200
|
+
// Trigger immediate status publish
|
|
201
|
+
if (statusBridge != nullptr) {
|
|
202
|
+
statusBridge->publishNow();
|
|
203
|
+
mqttClient.publish("mesh/response/command", "Status published");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else if (command == "broadcast") {
|
|
207
|
+
// Broadcast message to all mesh nodes
|
|
208
|
+
mesh.sendBroadcast(msg);
|
|
209
|
+
mqttClient.publish("mesh/response/command", "Message broadcasted");
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
IPAddress getlocalIP() {
|
|
215
|
+
return IPAddress(mesh.getStationIP());
|
|
216
|
+
}
|