@alteriom/painlessmesh 1.8.14 → 1.9.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/BRIDGE_TO_INTERNET.md +229 -0
- package/CHANGELOG.md +89 -1
- package/CONTRIBUTING.md +79 -0
- package/README.md +70 -143
- package/docs/README.md +1 -0
- package/docs/api/shared-gateway.md +1207 -0
- package/docs/troubleshooting/common-issues.md +28 -0
- package/docs/troubleshooting/faq.md +113 -12
- package/examples/basic/test/simulator/CMakeLists.txt +40 -0
- package/examples/basic/test/simulator/README.md +149 -0
- package/examples/basic/test/simulator/firmware/basic_firmware.hpp +117 -0
- package/examples/basic/test/simulator/scenarios/basic_mesh_test.yaml +81 -0
- package/examples/bridge/bridge.ino +17 -4
- package/examples/bridge_failover/README.md +81 -0
- package/examples/bridge_failover/bridge_failover.ino +51 -6
- package/examples/sharedGateway/README.md +235 -0
- package/examples/{meshCommandNode → sharedGateway}/platformio.ini +3 -2
- package/examples/sharedGateway/sharedGateway.ino +303 -0
- package/library.json +3 -22
- package/library.properties +1 -1
- package/package.json +3 -3
- package/src/arduino/wifi.hpp +380 -13
- package/src/painlessmesh/gateway.hpp +2120 -0
- package/src/painlessmesh/mesh.hpp +1034 -6
- package/src/painlessmesh/message_tracker.hpp +311 -0
- package/src/painlessmesh/protocol.hpp +6 -0
- package/DOCUMENTATION_INDEX.md +0 -146
- package/docs/API_DESIGN_GUIDELINES.md +0 -414
- package/docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md +0 -331
- package/docs/BOOLEAN_NAMING_CONVENTION.md +0 -235
- package/docs/BRIDGE_FAILOVER.md +0 -512
- package/docs/BRIDGE_HEALTH_MONITORING.md +0 -293
- package/docs/CHANNEL_SYNCHRONIZATION.md +0 -209
- package/docs/CREATE_MISSING_RELEASES.md +0 -321
- package/docs/DOCUMENTATION_MIGRATION_PLAN.md +0 -176
- package/docs/FAQ_VERSION_NUMBERS.md +0 -152
- package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +0 -1062
- package/docs/MESH_TOPOLOGY_GUIDE.md +0 -992
- package/docs/MESH_TOPOLOGY_PROGRESS.md +0 -422
- package/docs/MQTT_BRIDGE_COMMANDS.md +0 -894
- package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +0 -324
- package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +0 -576
- package/docs/MQTT_SCHEMA_COMPLIANCE.md +0 -340
- package/docs/MQTT_SCHEMA_PROPOSALS.md +0 -446
- package/docs/MQTT_SCHEMA_REVIEW.md +0 -690
- package/docs/OTA_COMMANDS_REFERENCE.md +0 -554
- package/docs/PHASE1_GUIDE.md +0 -349
- package/docs/PHASE2_GUIDE.md +0 -543
- package/docs/QUICK_REFERENCE_VERSIONING.md +0 -127
- package/docs/RELEASE_AGENT_SUMMARY.md +0 -386
- package/docs/SCHEMA_VALIDATION_CHECKLIST.md +0 -222
- package/docs/VERSION_MANAGEMENT.md +0 -213
- package/docs/archive/DOCUSAURUS_DEPLOYMENT.md +0 -166
- package/docs/archive/FEATURE_PROPOSALS.md +0 -337
- package/docs/archive/LIBRARY_JSON_FIX.md +0 -98
- package/docs/archive/LIBRARY_STRUCTURE_FIX.md +0 -215
- package/docs/archive/PHASE1_IMPLEMENTATION.md +0 -325
- package/docs/archive/PHASE2_IMPLEMENTATION.md +0 -567
- package/docs/archive/RELEASE_SUMMARY.md +0 -173
- package/docs/archive/SCONS_BUILD_FIX.md +0 -313
- package/docs/archive/TRIGGER_RELEASE.md +0 -280
- package/docs/archive/VECTOR_INCLUDE_FIX.md +0 -129
- package/docs/archive/ota-and-status-enhancements.md +0 -911
- package/docs/archive/ota-status-architecture-diagrams.md +0 -658
- package/docs/archive/ota-status-quick-reference.md +0 -284
- package/docs/design/.gitkeep +0 -1
- package/docs/design/STATION_CREDENTIALS_DESIGN.md +0 -182
- package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +0 -71
- package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +0 -1011
- package/docs/development/DOCKER_TESTING.md +0 -196
- package/docs/development/PLATFORMIO_USAGE.md +0 -180
- package/docs/development/TESTING_SUMMARY.md +0 -126
- package/docs/development/contributing.md +0 -301
- package/docs/development/documentation.md +0 -583
- package/docs/features/DIAGNOSTICS_API.md +0 -534
- package/docs/implementation/BRIDGE_ARCHITECTURE_IMPLEMENTATION.md +0 -340
- package/docs/implementation/BRIDGE_HEALTH_MONITORING_IMPLEMENTATION.md +0 -213
- package/docs/implementation/BRIDGE_STATUS_FEATURE.md +0 -635
- package/docs/implementation/DIAGNOSTICS_API_IMPLEMENTATION.md +0 -232
- package/docs/implementation/IMPLEMENTATION_COMPLETE.md +0 -228
- package/docs/implementation/IMPLEMENTATION_NTP_TIME_SYNC.md +0 -325
- package/docs/implementation/IMPLEMENTATION_SUMMARY.md +0 -316
- package/docs/implementation/MESSAGE_QUEUE_IMPLEMENTATION.md +0 -405
- package/docs/implementation/MULTI_BRIDGE_IMPLEMENTATION.md +0 -520
- package/docs/implementation/NTP_TIME_SYNC_FEATURE.md +0 -392
- package/docs/improvements/FUTURE_PROPOSALS.md +0 -1016
- package/docs/improvements/IMPLEMENTATION_HISTORY.md +0 -1091
- package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +0 -709
- package/docs/improvements/README.md +0 -212
- package/docs/internal/CUSTOM_AGENT_ANALYSIS.md +0 -391
- package/docs/internal/ISSUE_65_VERIFICATION.md +0 -947
- package/docs/internal/ISSUE_66_CLOSURE.md +0 -249
- package/docs/internal/ISSUE_66_STATUS.md +0 -316
- package/docs/internal/PR_SUMMARY.md +0 -315
- package/docs/internal/REVIEW_SUMMARY.md +0 -332
- package/docs/multi-bridge-setup.md +0 -1025
- package/docs/platformio-publishing.md +0 -255
- package/docs/platformio-setup-summary.md +0 -121
- package/docs/releases/ANNOUNCEMENT_v1.8.6.md +0 -63
- package/docs/releases/ANNOUNCEMENT_v1.8.7.md +0 -113
- package/docs/releases/BRIDGE_STATUS_SELF_REGISTRATION_FIX.md +0 -221
- package/docs/releases/FEATURE_HISTORY.md +0 -543
- package/docs/releases/GITHUB_RELEASE_v1.8.6.md +0 -71
- package/docs/releases/GITHUB_RELEASE_v1.8.7.md +0 -90
- package/docs/releases/PATCH_v1.7.2.md +0 -262
- package/docs/releases/PATCH_v1.7.3.md +0 -262
- package/docs/releases/PATCH_v1.7.4.md +0 -219
- package/docs/releases/PHASE1_SUMMARY.md +0 -246
- package/docs/releases/PHASE2_SUMMARY.md +0 -499
- package/docs/releases/PUBLISH_v1.8.0_INSTRUCTIONS.md +0 -163
- package/docs/releases/QUICK_START_RELEASES.md +0 -113
- package/docs/releases/RELEASE_CHECKLIST_1.8.10.md +0 -331
- package/docs/releases/RELEASE_CHECKLIST_1.8.9.md +0 -207
- package/docs/releases/RELEASE_CHECKLIST_v1.7.4.md +0 -253
- package/docs/releases/RELEASE_CHECKLIST_v1.7.5.md +0 -315
- package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +0 -389
- package/docs/releases/RELEASE_CHECKLIST_v1.8.0.md +0 -331
- package/docs/releases/RELEASE_CHECKLIST_v1.8.2.md +0 -309
- package/docs/releases/RELEASE_NOTES_1.7.0.md +0 -539
- package/docs/releases/RELEASE_NOTES_1.8.10.md +0 -239
- package/docs/releases/RELEASE_NOTES_1.8.9.md +0 -213
- package/docs/releases/RELEASE_NOTES_v1.8.0.md +0 -685
- package/docs/releases/RELEASE_NOTES_v1.8.1.md +0 -221
- package/docs/releases/RELEASE_NOTES_v1.8.2.md +0 -421
- package/docs/releases/RELEASE_NOTES_v1.8.3.md +0 -292
- package/docs/releases/RELEASE_NOTES_v1.8.4.md +0 -277
- package/docs/releases/RELEASE_NOTES_v1.8.6.md +0 -205
- package/docs/releases/RELEASE_NOTES_v1.8.7.md +0 -184
- package/docs/releases/RELEASE_PLAN_v1.7.6.md +0 -816
- package/docs/releases/RELEASE_SUMMARY_1.8.10.md +0 -193
- package/docs/releases/RELEASE_SUMMARY_v1.7.4.md +0 -276
- package/docs/releases/RELEASE_SUMMARY_v1.7.5.md +0 -322
- package/docs/releases/RELEASE_SUMMARY_v1.7.6.md +0 -436
- package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +0 -391
- package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +0 -523
- package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +0 -542
- package/docs/troubleshooting/ARDUINO_IDE_VERSION_FIX_SUMMARY.md +0 -229
- package/docs/troubleshooting/ARDUINO_LIBRARY_NAME_FIX.md +0 -197
- package/docs/troubleshooting/CRASH_QUICK_REF.md +0 -93
- package/docs/troubleshooting/ESP32_C6_COMPATIBILITY.md +0 -157
- package/docs/troubleshooting/FREERTOS_ASSERTION_FAILURE.md +0 -288
- package/docs/troubleshooting/FREERTOS_FIX_IMPLEMENTATION.md +0 -267
- package/docs/troubleshooting/NPM_PUBLISHING_ISSUE_SUMMARY.md +0 -110
- package/docs/troubleshooting/PAINLESSMESH_V1.7.4_COMPILATION_ISSUES.md +0 -547
- package/docs/troubleshooting/QUICK_FIX_FREERTOS.md +0 -164
- package/docs/troubleshooting/SENSOR_NODE_CONNECTION_CRASH.md +0 -264
- package/docs/troubleshooting/station-reconnection-issues.md +0 -172
- package/docs/v1.7.7_MQTT_IMPROVEMENTS.md +0 -794
- package/docs/wiki/API-Reference.md +0 -246
- package/docs/wiki/Complete-Documentation.md +0 -123
- package/examples/alteriomImproved/alteriom_sensor_package.hpp +0 -224
- package/examples/alteriomImproved/improved_sensor_node.ino +0 -248
- package/examples/alteriomImproved/platformio.ini +0 -32
- package/examples/alteriomMetricsHealth/alteriom_sensor_package.hpp +0 -796
- package/examples/alteriomMetricsHealth/metrics_health_node.ino +0 -429
- package/examples/alteriomMetricsHealth/platformio.ini +0 -26
- package/examples/alteriomPhase1/alteriom_sensor_package.hpp +0 -224
- package/examples/alteriomPhase1/phase1_features.ino +0 -242
- package/examples/alteriomPhase1/platformio.ini +0 -26
- package/examples/alteriomPhase2/alteriom_sensor_package.hpp +0 -224
- package/examples/alteriomPhase2/phase2_features.ino +0 -186
- package/examples/alteriomPhase2/platformio.ini +0 -26
- package/examples/alteriomSensorNode/alteriom_sensor_node.ino +0 -186
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +0 -1227
- package/examples/alteriomSensorNode/platformio.ini +0 -26
- package/examples/bridge/alteriom_sensor_package.hpp +0 -1170
- package/examples/bridge/bridge_health_monitoring_example.ino +0 -188
- package/examples/bridge/enhanced_mqtt_bridge.hpp +0 -610
- package/examples/bridge/enhanced_mqtt_bridge_example.ino +0 -226
- package/examples/bridge/mesh_event_publisher.hpp +0 -253
- package/examples/bridge/mesh_topology_reporter.hpp +0 -303
- package/examples/bridge/mqtt_command_bridge.hpp +0 -459
- package/examples/bridge/mqtt_status_bridge.hpp +0 -519
- package/examples/bridgeAwareSensorNode/alteriom_sensor_package.hpp +0 -1227
- package/examples/bridgeAwareSensorNode/bridgeAwareSensorNode.ino +0 -342
- package/examples/bridgeAwareSensorNode/platformio.ini +0 -26
- package/examples/diagnosticsExample/diagnosticsExample.ino +0 -171
- package/examples/diagnosticsExample/platformio.ini +0 -26
- package/examples/echoNode/echoNode.ino +0 -33
- package/examples/echoNode/platformio.ini +0 -26
- package/examples/meshCommandNode/alteriom_sensor_package.hpp +0 -235
- package/examples/meshCommandNode/meshCommandNode.ino +0 -265
- package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +0 -235
- package/examples/mqttCommandBridge/mesh_event_publisher.hpp +0 -253
- package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +0 -303
- package/examples/mqttCommandBridge/mqttCommandBridge.ino +0 -254
- package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +0 -462
- package/examples/mqttCommandBridge/platformio.ini +0 -27
- package/examples/mqttStatusBridge/mqttStatusBridge.ino +0 -218
- package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +0 -522
- package/examples/mqttStatusBridge/platformio.ini +0 -27
- package/examples/mqttTopologyTest/README.md +0 -467
- package/examples/mqttTopologyTest/mqttTopologyTest.ino +0 -754
- package/examples/mqttTopologyTest/platformio.ini +0 -27
- package/examples/multi_bridge/README.md +0 -346
- package/examples/multi_bridge/primary_bridge.ino +0 -96
- package/examples/multi_bridge/regular_node.ino +0 -141
- package/examples/multi_bridge/secondary_bridge.ino +0 -111
- package/examples/ntpTimeSyncBridge/alteriom_sensor_package.hpp +0 -1383
- package/examples/ntpTimeSyncBridge/ntpTimeSyncBridge.ino +0 -86
- package/examples/ntpTimeSyncNode/alteriom_sensor_package.hpp +0 -1383
- package/examples/ntpTimeSyncNode/ntpTimeSyncNode.ino +0 -109
- package/examples/queued_alarms/README.md +0 -390
- package/examples/queued_alarms/queued_alarms.ino +0 -265
- package/examples/routing_demo/README.md +0 -172
- package/examples/routing_demo/routing_demo.ino +0 -102
- package/examples/rtcIntegration/README.md +0 -294
- package/examples/rtcIntegration/rtcIntegration.ino +0 -210
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enhanced MQTT Bridge Example - painlessMesh v1.7.7
|
|
3
|
-
*
|
|
4
|
-
* Demonstrates the enhanced MQTT bridge with:
|
|
5
|
-
* - Command handlers for requesting metrics and health checks
|
|
6
|
-
* - Aggregated network statistics
|
|
7
|
-
* - Real-time metric collection from mesh nodes
|
|
8
|
-
* - Health monitoring with alerting
|
|
9
|
-
*
|
|
10
|
-
* This gateway node bridges between MQTT and the mesh network,
|
|
11
|
-
* enabling remote monitoring and control.
|
|
12
|
-
*
|
|
13
|
-
* Hardware: ESP32 with WiFi (ESP8266 also supported)
|
|
14
|
-
*
|
|
15
|
-
* MQTT Topics:
|
|
16
|
-
* Subscribe (Commands):
|
|
17
|
-
* - mesh/command/request_metrics {"node_id": 0} // 0 = all nodes
|
|
18
|
-
* - mesh/command/request_health {"node_id": 12345}
|
|
19
|
-
* - mesh/command/get_aggregated {}
|
|
20
|
-
*
|
|
21
|
-
* Publish (Data):
|
|
22
|
-
* - mesh/metrics/{node_id} // Individual node metrics
|
|
23
|
-
* - mesh/health/{node_id} // Individual node health
|
|
24
|
-
* - mesh/aggregated/metrics // Aggregated mesh-wide metrics
|
|
25
|
-
* - mesh/aggregated/health // Aggregated mesh health summary
|
|
26
|
-
* - mesh/alerts/critical // Critical health alerts
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
#include "painlessMesh.h"
|
|
30
|
-
#include <WiFi.h>
|
|
31
|
-
#include <PubSubClient.h>
|
|
32
|
-
#include "enhanced_mqtt_bridge.hpp"
|
|
33
|
-
|
|
34
|
-
// Mesh Configuration
|
|
35
|
-
#define MESH_PREFIX "AlteriomMesh"
|
|
36
|
-
#define MESH_PASSWORD "your_password"
|
|
37
|
-
#define MESH_PORT 5555
|
|
38
|
-
|
|
39
|
-
// WiFi Station Configuration (for MQTT connection)
|
|
40
|
-
#define STATION_SSID "your_wifi_ssid"
|
|
41
|
-
#define STATION_PASSWORD "your_wifi_password"
|
|
42
|
-
|
|
43
|
-
// MQTT Configuration
|
|
44
|
-
#define MQTT_BROKER "192.168.1.100" // Your MQTT broker IP
|
|
45
|
-
#define MQTT_PORT 1883
|
|
46
|
-
#define MQTT_USER "mqtt_user" // Leave empty if no auth
|
|
47
|
-
#define MQTT_PASSWORD "mqtt_password" // Leave empty if no auth
|
|
48
|
-
|
|
49
|
-
Scheduler userScheduler;
|
|
50
|
-
painlessMesh mesh;
|
|
51
|
-
WiFiClient espClient;
|
|
52
|
-
PubSubClient mqttClient(espClient);
|
|
53
|
-
EnhancedMqttBridge* bridge = nullptr;
|
|
54
|
-
|
|
55
|
-
// Task for reconnecting to MQTT
|
|
56
|
-
Task taskReconnectMQTT(5000, TASK_FOREVER, &reconnectMQTT);
|
|
57
|
-
|
|
58
|
-
void setup() {
|
|
59
|
-
Serial.begin(115200);
|
|
60
|
-
Serial.println("\n\n=== Enhanced MQTT Bridge for painlessMesh v1.7.7 ===");
|
|
61
|
-
|
|
62
|
-
// Initialize mesh
|
|
63
|
-
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
64
|
-
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
|
|
65
|
-
|
|
66
|
-
// Configure mesh callbacks
|
|
67
|
-
mesh.onNewConnection(&newConnectionCallback);
|
|
68
|
-
mesh.onChangedConnections(&changedConnectionCallback);
|
|
69
|
-
mesh.onDroppedConnection(&droppedConnectionCallback);
|
|
70
|
-
|
|
71
|
-
// Connect to WiFi for MQTT
|
|
72
|
-
WiFi.mode(WIFI_AP_STA);
|
|
73
|
-
WiFi.begin(STATION_SSID, STATION_PASSWORD);
|
|
74
|
-
|
|
75
|
-
Serial.print("Connecting to WiFi");
|
|
76
|
-
while (WiFi.status() != WL_CONNECTED) {
|
|
77
|
-
delay(500);
|
|
78
|
-
Serial.print(".");
|
|
79
|
-
}
|
|
80
|
-
Serial.println(" Connected!");
|
|
81
|
-
Serial.printf("IP Address: %s\n", WiFi.localIP().toString().c_str());
|
|
82
|
-
|
|
83
|
-
// Configure MQTT
|
|
84
|
-
mqttClient.setServer(MQTT_BROKER, MQTT_PORT);
|
|
85
|
-
mqttClient.setCallback(mqttCallback);
|
|
86
|
-
mqttClient.setBufferSize(2048); // Increase buffer for large messages
|
|
87
|
-
|
|
88
|
-
// Connect to MQTT
|
|
89
|
-
connectMQTT();
|
|
90
|
-
|
|
91
|
-
// Create and initialize enhanced bridge
|
|
92
|
-
bridge = new EnhancedMqttBridge(mesh, mqttClient);
|
|
93
|
-
bridge->setTopicPrefix("mesh/");
|
|
94
|
-
bridge->setDeviceId("GATEWAY-" + String(mesh.getNodeId(), HEX));
|
|
95
|
-
bridge->enableAggregation(true);
|
|
96
|
-
bridge->setAggregationInterval(60000); // 60 seconds
|
|
97
|
-
bridge->begin();
|
|
98
|
-
|
|
99
|
-
// Add MQTT reconnect task
|
|
100
|
-
userScheduler.addTask(taskReconnectMQTT);
|
|
101
|
-
taskReconnectMQTT.enable();
|
|
102
|
-
|
|
103
|
-
Serial.printf("Gateway Node ID: %u\n", mesh.getNodeId());
|
|
104
|
-
Serial.println("Enhanced MQTT Bridge ready!");
|
|
105
|
-
Serial.println("\nAvailable MQTT commands:");
|
|
106
|
-
Serial.println(" mesh/command/request_metrics {\"node_id\": 0}");
|
|
107
|
-
Serial.println(" mesh/command/request_health {\"node_id\": 12345}");
|
|
108
|
-
Serial.println(" mesh/command/get_aggregated {}");
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
void loop() {
|
|
112
|
-
mesh.update();
|
|
113
|
-
|
|
114
|
-
// Handle MQTT
|
|
115
|
-
if (mqttClient.connected()) {
|
|
116
|
-
mqttClient.loop();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Update bridge (handles aggregation)
|
|
120
|
-
if (bridge) {
|
|
121
|
-
bridge->update();
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* MQTT callback - receives commands from MQTT
|
|
127
|
-
*/
|
|
128
|
-
void mqttCallback(char* topic, byte* payload, unsigned int length) {
|
|
129
|
-
// Convert to String
|
|
130
|
-
String topicStr = String(topic);
|
|
131
|
-
String payloadStr = "";
|
|
132
|
-
for (unsigned int i = 0; i < length; i++) {
|
|
133
|
-
payloadStr += (char)payload[i];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
Serial.printf("\n[MQTT] Message on topic: %s\n", topic);
|
|
137
|
-
Serial.printf("Payload: %s\n", payloadStr.c_str());
|
|
138
|
-
|
|
139
|
-
// Forward to bridge for handling
|
|
140
|
-
if (bridge) {
|
|
141
|
-
bridge->handleMQTTMessage(topicStr, payloadStr);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Connect to MQTT broker
|
|
147
|
-
*/
|
|
148
|
-
void connectMQTT() {
|
|
149
|
-
Serial.print("Connecting to MQTT broker...");
|
|
150
|
-
|
|
151
|
-
String clientId = "painlessMesh-" + String(mesh.getNodeId());
|
|
152
|
-
|
|
153
|
-
bool connected = false;
|
|
154
|
-
if (strlen(MQTT_USER) > 0) {
|
|
155
|
-
connected = mqttClient.connect(clientId.c_str(), MQTT_USER, MQTT_PASSWORD);
|
|
156
|
-
} else {
|
|
157
|
-
connected = mqttClient.connect(clientId.c_str());
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (connected) {
|
|
161
|
-
Serial.println(" Connected!");
|
|
162
|
-
|
|
163
|
-
// Subscribe to command topics
|
|
164
|
-
mqttClient.subscribe("mesh/command/request_metrics");
|
|
165
|
-
mqttClient.subscribe("mesh/command/request_health");
|
|
166
|
-
mqttClient.subscribe("mesh/command/get_aggregated");
|
|
167
|
-
|
|
168
|
-
Serial.println("Subscribed to command topics");
|
|
169
|
-
|
|
170
|
-
// Publish connection announcement
|
|
171
|
-
String topic = "mesh/gateway/status";
|
|
172
|
-
String payload = "{\"status\":\"connected\",\"node_id\":" + String(mesh.getNodeId()) + "}";
|
|
173
|
-
mqttClient.publish(topic.c_str(), payload.c_str());
|
|
174
|
-
} else {
|
|
175
|
-
Serial.printf(" Failed! (rc=%d)\n", mqttClient.state());
|
|
176
|
-
Serial.println("Will retry in 5 seconds...");
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Reconnect to MQTT if disconnected
|
|
182
|
-
*/
|
|
183
|
-
void reconnectMQTT() {
|
|
184
|
-
if (!mqttClient.connected() && WiFi.status() == WL_CONNECTED) {
|
|
185
|
-
Serial.println("\nMQTT disconnected, attempting to reconnect...");
|
|
186
|
-
connectMQTT();
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Mesh callbacks
|
|
191
|
-
void newConnectionCallback(uint32_t nodeId) {
|
|
192
|
-
Serial.printf("\n[Mesh] New connection: %u\n", nodeId);
|
|
193
|
-
Serial.printf("Total nodes in mesh: %d\n", mesh.getNodeList().size() + 1);
|
|
194
|
-
|
|
195
|
-
// Publish to MQTT
|
|
196
|
-
if (mqttClient.connected()) {
|
|
197
|
-
String topic = "mesh/events/connection";
|
|
198
|
-
String payload = "{\"event\":\"new_connection\",\"node_id\":" + String(nodeId) +
|
|
199
|
-
",\"total_nodes\":" + String(mesh.getNodeList().size() + 1) + "}";
|
|
200
|
-
mqttClient.publish(topic.c_str(), payload.c_str());
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
void changedConnectionCallback() {
|
|
205
|
-
Serial.println("\n[Mesh] Topology changed");
|
|
206
|
-
|
|
207
|
-
// Publish to MQTT
|
|
208
|
-
if (mqttClient.connected()) {
|
|
209
|
-
auto nodes = mesh.getNodeList();
|
|
210
|
-
String topic = "mesh/events/topology_change";
|
|
211
|
-
String payload = "{\"event\":\"topology_changed\",\"node_count\":" +
|
|
212
|
-
String(nodes.size() + 1) + "}";
|
|
213
|
-
mqttClient.publish(topic.c_str(), payload.c_str());
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
void droppedConnectionCallback(uint32_t nodeId) {
|
|
218
|
-
Serial.printf("\n[Mesh] Connection dropped: %u\n", nodeId);
|
|
219
|
-
|
|
220
|
-
// Publish to MQTT
|
|
221
|
-
if (mqttClient.connected()) {
|
|
222
|
-
String topic = "mesh/events/disconnection";
|
|
223
|
-
String payload = "{\"event\":\"connection_dropped\",\"node_id\":" + String(nodeId) + "}";
|
|
224
|
-
mqttClient.publish(topic.c_str(), payload.c_str());
|
|
225
|
-
}
|
|
226
|
-
}
|
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
#ifndef MESH_EVENT_PUBLISHER_HPP
|
|
2
|
-
#define MESH_EVENT_PUBLISHER_HPP
|
|
3
|
-
|
|
4
|
-
#include "painlessMesh.h"
|
|
5
|
-
#include <PubSubClient.h>
|
|
6
|
-
#include <ArduinoJson.h>
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* MeshEventPublisher - Publish real-time mesh events
|
|
10
|
-
*
|
|
11
|
-
* Publishes mesh state change events conforming to @alteriom/mqtt-schema v0.5.0
|
|
12
|
-
* mesh_event.schema.json specification.
|
|
13
|
-
*
|
|
14
|
-
* Event Types:
|
|
15
|
-
* - node_join: New node entered mesh
|
|
16
|
-
* - node_leave: Node left mesh (clean disconnect)
|
|
17
|
-
* - connection_lost: Direct connection failed
|
|
18
|
-
* - connection_restored: Connection recovered
|
|
19
|
-
*
|
|
20
|
-
* @author Alteriom Development Team
|
|
21
|
-
* @date October 12, 2025
|
|
22
|
-
*/
|
|
23
|
-
class MeshEventPublisher {
|
|
24
|
-
private:
|
|
25
|
-
painlessMesh& mesh;
|
|
26
|
-
PubSubClient& mqttClient;
|
|
27
|
-
String meshId;
|
|
28
|
-
String eventTopic;
|
|
29
|
-
String firmwareVersion;
|
|
30
|
-
|
|
31
|
-
public:
|
|
32
|
-
MeshEventPublisher(painlessMesh& mesh, PubSubClient& mqttClient,
|
|
33
|
-
const String& meshId, const String& topic = "alteriom/mesh/events",
|
|
34
|
-
const String& fwVersion = "GW 2.3.4")
|
|
35
|
-
: mesh(mesh), mqttClient(mqttClient), meshId(meshId),
|
|
36
|
-
eventTopic(topic), firmwareVersion(fwVersion) {}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Publish node join event
|
|
40
|
-
* Called when a new node connects to the mesh
|
|
41
|
-
*/
|
|
42
|
-
void publishNodeJoin(uint32_t nodeId) {
|
|
43
|
-
DynamicJsonDocument doc(1024);
|
|
44
|
-
|
|
45
|
-
// Envelope
|
|
46
|
-
doc["schema_version"] = 1;
|
|
47
|
-
doc["device_id"] = generateDeviceId(mesh.getNodeId());
|
|
48
|
-
doc["device_type"] = "gateway";
|
|
49
|
-
doc["timestamp"] = getISO8601Timestamp();
|
|
50
|
-
doc["firmware_version"] = firmwareVersion;
|
|
51
|
-
|
|
52
|
-
// Event
|
|
53
|
-
doc["event"] = "mesh_event";
|
|
54
|
-
doc["event_type"] = "node_join";
|
|
55
|
-
doc["mesh_id"] = meshId;
|
|
56
|
-
|
|
57
|
-
JsonArray affected = doc.createNestedArray("affected_nodes");
|
|
58
|
-
affected.add(generateDeviceId(nodeId));
|
|
59
|
-
|
|
60
|
-
JsonObject details = doc.createNestedObject("details");
|
|
61
|
-
details["total_nodes"] = mesh.getNodeList().size() + 1;
|
|
62
|
-
details["timestamp"] = getISO8601Timestamp();
|
|
63
|
-
|
|
64
|
-
publishEvent(doc, "Node Join");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Publish node leave event
|
|
69
|
-
* Called when a node disconnects from the mesh
|
|
70
|
-
*/
|
|
71
|
-
void publishNodeLeave(uint32_t nodeId) {
|
|
72
|
-
DynamicJsonDocument doc(1024);
|
|
73
|
-
|
|
74
|
-
// Envelope
|
|
75
|
-
doc["schema_version"] = 1;
|
|
76
|
-
doc["device_id"] = generateDeviceId(mesh.getNodeId());
|
|
77
|
-
doc["device_type"] = "gateway";
|
|
78
|
-
doc["timestamp"] = getISO8601Timestamp();
|
|
79
|
-
doc["firmware_version"] = firmwareVersion;
|
|
80
|
-
|
|
81
|
-
// Event
|
|
82
|
-
doc["event"] = "mesh_event";
|
|
83
|
-
doc["event_type"] = "node_leave";
|
|
84
|
-
doc["mesh_id"] = meshId;
|
|
85
|
-
|
|
86
|
-
JsonArray affected = doc.createNestedArray("affected_nodes");
|
|
87
|
-
affected.add(generateDeviceId(nodeId));
|
|
88
|
-
|
|
89
|
-
JsonObject details = doc.createNestedObject("details");
|
|
90
|
-
details["reason"] = "connection_lost";
|
|
91
|
-
details["last_seen"] = getISO8601Timestamp();
|
|
92
|
-
details["total_nodes"] = mesh.getNodeList().size() + 1;
|
|
93
|
-
|
|
94
|
-
publishEvent(doc, "Node Leave");
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Publish connection lost event
|
|
99
|
-
* Called when a direct connection fails
|
|
100
|
-
*/
|
|
101
|
-
void publishConnectionLost(uint32_t nodeId) {
|
|
102
|
-
DynamicJsonDocument doc(1024);
|
|
103
|
-
|
|
104
|
-
doc["schema_version"] = 1;
|
|
105
|
-
doc["device_id"] = generateDeviceId(mesh.getNodeId());
|
|
106
|
-
doc["device_type"] = "gateway";
|
|
107
|
-
doc["timestamp"] = getISO8601Timestamp();
|
|
108
|
-
doc["firmware_version"] = firmwareVersion;
|
|
109
|
-
|
|
110
|
-
doc["event"] = "mesh_event";
|
|
111
|
-
doc["event_type"] = "connection_lost";
|
|
112
|
-
doc["mesh_id"] = meshId;
|
|
113
|
-
|
|
114
|
-
JsonArray affected = doc.createNestedArray("affected_nodes");
|
|
115
|
-
affected.add(generateDeviceId(nodeId));
|
|
116
|
-
|
|
117
|
-
JsonObject details = doc.createNestedObject("details");
|
|
118
|
-
details["reason"] = "timeout";
|
|
119
|
-
details["timestamp"] = getISO8601Timestamp();
|
|
120
|
-
|
|
121
|
-
publishEvent(doc, "Connection Lost");
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Publish connection restored event
|
|
126
|
-
* Called when a connection is re-established
|
|
127
|
-
*/
|
|
128
|
-
void publishConnectionRestored(uint32_t nodeId) {
|
|
129
|
-
DynamicJsonDocument doc(1024);
|
|
130
|
-
|
|
131
|
-
doc["schema_version"] = 1;
|
|
132
|
-
doc["device_id"] = generateDeviceId(mesh.getNodeId());
|
|
133
|
-
doc["device_type"] = "gateway";
|
|
134
|
-
doc["timestamp"] = getISO8601Timestamp();
|
|
135
|
-
doc["firmware_version"] = firmwareVersion;
|
|
136
|
-
|
|
137
|
-
doc["event"] = "mesh_event";
|
|
138
|
-
doc["event_type"] = "connection_restored";
|
|
139
|
-
doc["mesh_id"] = meshId;
|
|
140
|
-
|
|
141
|
-
JsonArray affected = doc.createNestedArray("affected_nodes");
|
|
142
|
-
affected.add(generateDeviceId(nodeId));
|
|
143
|
-
|
|
144
|
-
JsonObject details = doc.createNestedObject("details");
|
|
145
|
-
details["timestamp"] = getISO8601Timestamp();
|
|
146
|
-
|
|
147
|
-
publishEvent(doc, "Connection Restored");
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Publish network split event
|
|
152
|
-
* Called when mesh partitions into separate segments
|
|
153
|
-
*/
|
|
154
|
-
void publishNetworkSplit() {
|
|
155
|
-
DynamicJsonDocument doc(1024);
|
|
156
|
-
|
|
157
|
-
doc["schema_version"] = 1;
|
|
158
|
-
doc["device_id"] = generateDeviceId(mesh.getNodeId());
|
|
159
|
-
doc["device_type"] = "gateway";
|
|
160
|
-
doc["timestamp"] = getISO8601Timestamp();
|
|
161
|
-
doc["firmware_version"] = firmwareVersion;
|
|
162
|
-
|
|
163
|
-
doc["event"] = "mesh_event";
|
|
164
|
-
doc["event_type"] = "network_split";
|
|
165
|
-
doc["mesh_id"] = meshId;
|
|
166
|
-
|
|
167
|
-
JsonArray affected = doc.createNestedArray("affected_nodes");
|
|
168
|
-
// TODO: Detect which nodes are in different partitions
|
|
169
|
-
|
|
170
|
-
JsonObject details = doc.createNestedObject("details");
|
|
171
|
-
details["timestamp"] = getISO8601Timestamp();
|
|
172
|
-
details["partition_count"] = 2; // TODO: Calculate actual partitions
|
|
173
|
-
|
|
174
|
-
publishEvent(doc, "Network Split");
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Publish network merged event
|
|
179
|
-
* Called when mesh partitions rejoin
|
|
180
|
-
*/
|
|
181
|
-
void publishNetworkMerged() {
|
|
182
|
-
DynamicJsonDocument doc(1024);
|
|
183
|
-
|
|
184
|
-
doc["schema_version"] = 1;
|
|
185
|
-
doc["device_id"] = generateDeviceId(mesh.getNodeId());
|
|
186
|
-
doc["device_type"] = "gateway";
|
|
187
|
-
doc["timestamp"] = getISO8601Timestamp();
|
|
188
|
-
doc["firmware_version"] = firmwareVersion;
|
|
189
|
-
|
|
190
|
-
doc["event"] = "mesh_event";
|
|
191
|
-
doc["event_type"] = "network_merged";
|
|
192
|
-
doc["mesh_id"] = meshId;
|
|
193
|
-
|
|
194
|
-
JsonArray affected = doc.createNestedArray("affected_nodes");
|
|
195
|
-
// TODO: List nodes that rejoined
|
|
196
|
-
|
|
197
|
-
JsonObject details = doc.createNestedObject("details");
|
|
198
|
-
details["timestamp"] = getISO8601Timestamp();
|
|
199
|
-
|
|
200
|
-
publishEvent(doc, "Network Merged");
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
private:
|
|
204
|
-
/**
|
|
205
|
-
* Internal method to publish event to MQTT
|
|
206
|
-
*/
|
|
207
|
-
void publishEvent(const DynamicJsonDocument& doc, const char* eventName) {
|
|
208
|
-
if (!mqttClient.connected()) {
|
|
209
|
-
Serial.printf("[Event] ⚠️ MQTT not connected, cannot publish %s\n", eventName);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
String payload;
|
|
214
|
-
serializeJson(doc, payload);
|
|
215
|
-
|
|
216
|
-
bool success = mqttClient.publish(eventTopic.c_str(), payload.c_str());
|
|
217
|
-
|
|
218
|
-
if (success) {
|
|
219
|
-
Serial.printf("[Event] ✅ Published: %s (node: %s)\n",
|
|
220
|
-
eventName,
|
|
221
|
-
doc["affected_nodes"][0].as<const char*>());
|
|
222
|
-
} else {
|
|
223
|
-
Serial.printf("[Event] ❌ Failed to publish: %s\n", eventName);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Generate device ID in Alteriom format (ALT-XXXXXXXXXXXX)
|
|
229
|
-
*/
|
|
230
|
-
String generateDeviceId(uint32_t nodeId) {
|
|
231
|
-
char deviceId[20];
|
|
232
|
-
snprintf(deviceId, sizeof(deviceId), "ALT-%012X", nodeId);
|
|
233
|
-
return String(deviceId);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Get current timestamp in ISO 8601 format
|
|
238
|
-
* TODO: Use proper NTP time if available
|
|
239
|
-
*/
|
|
240
|
-
String getISO8601Timestamp() {
|
|
241
|
-
// For now, use epoch-based timestamp
|
|
242
|
-
// In production, this should use actual NTP-synced time
|
|
243
|
-
unsigned long ms = millis();
|
|
244
|
-
char timestamp[32];
|
|
245
|
-
snprintf(timestamp, sizeof(timestamp), "2025-10-12T%02lu:%02lu:%02luZ",
|
|
246
|
-
(ms / 3600000) % 24,
|
|
247
|
-
(ms / 60000) % 60,
|
|
248
|
-
(ms / 1000) % 60);
|
|
249
|
-
return String(timestamp);
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
#endif // MESH_EVENT_PUBLISHER_HPP
|