@alteriom/painlessmesh 1.7.8 → 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 +139 -3
- package/README.md +114 -4
- package/RELEASE_GUIDE.md +57 -8
- 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/README.md +2 -1
- package/docs/RELEASE_AGENT_SUMMARY.md +386 -0
- package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +523 -0
- package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +542 -0
- package/docs/troubleshooting/ESP32_C6_COMPATIBILITY.md +157 -0
- package/docs/troubleshooting/common-issues.md +28 -0
- package/examples/alteriom/alteriom_sensor_package.hpp +233 -1
- package/examples/alteriom/platformio.ini +1 -1
- package/examples/alteriomImproved/platformio.ini +1 -1
- package/examples/alteriomMetricsHealth/metrics_health_node.ino +18 -7
- package/examples/alteriomMetricsHealth/platformio.ini +1 -1
- package/examples/alteriomPhase1/platformio.ini +1 -1
- package/examples/alteriomPhase2/platformio.ini +1 -1
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +1014 -11
- package/examples/alteriomSensorNode/platformio.ini +1 -1
- package/examples/basic/basic.ino +6 -2
- package/examples/basic/platformio.ini +1 -1
- package/examples/bridge/alteriom_sensor_package.hpp +1170 -0
- package/examples/bridge/bridge.ino +44 -23
- package/examples/bridge/bridge_health_monitoring_example.ino +188 -0
- package/examples/bridge/enhanced_mqtt_bridge.hpp +1 -1
- package/examples/bridge/mqtt_command_bridge.hpp +2 -2
- package/examples/bridge/platformio.ini +2 -1
- 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/echoNode/platformio.ini +1 -1
- package/examples/logClient/platformio.ini +1 -1
- package/examples/logServer/platformio.ini +1 -1
- package/examples/mqttStatusBridge/platformio.ini +1 -1
- package/examples/namedMesh/platformio.ini +1 -1
- 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/otaReceiver/platformio.ini +1 -1
- package/examples/rtcIntegration/README.md +235 -0
- package/examples/rtcIntegration/rtcIntegration.ino +196 -0
- package/examples/startHere/platformio.ini +1 -1
- package/examples/webServer/platformio.ini +1 -1
- package/library.json +93 -53
- package/library.properties +1 -1
- package/package.json +2 -2
- package/src/arduino/wifi.hpp +581 -0
- package/src/painlessMeshSTA.cpp +68 -0
- package/src/painlessMeshSTA.h +3 -0
- package/src/painlessmesh/mesh.hpp +1127 -4
- package/src/painlessmesh/rtc.hpp +203 -0
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
This guide covers the most frequently encountered problems when working with painlessMesh and their solutions.
|
|
4
4
|
|
|
5
|
+
## Platform-Specific Issues
|
|
6
|
+
|
|
7
|
+
### ESP32-C6 Crashes on Startup
|
|
8
|
+
|
|
9
|
+
**Symptoms:**
|
|
10
|
+
- Device crashes immediately after mesh initialization
|
|
11
|
+
- Endless reboot loop
|
|
12
|
+
- Error message: `assert failed: tcp_alloc ... (Required to lock TCPIP core functionality!)`
|
|
13
|
+
|
|
14
|
+
**Solution:**
|
|
15
|
+
|
|
16
|
+
This is a known compatibility issue with ESP32-C6 and newer ESP32 variants. See the dedicated guide:
|
|
17
|
+
|
|
18
|
+
📖 **[ESP32-C6 Compatibility Guide](ESP32_C6_COMPATIBILITY.md)**
|
|
19
|
+
|
|
20
|
+
**Quick Fix:**
|
|
21
|
+
Update your AsyncTCP library to version 3.3.0 or newer, or use the ESP32Async library which includes proper LWIP locking for Arduino ESP32 core 3.1.0+.
|
|
22
|
+
|
|
23
|
+
For PlatformIO, add to your `platformio.ini`:
|
|
24
|
+
```ini
|
|
25
|
+
lib_deps =
|
|
26
|
+
esp32async/AsyncTCP @ ^3.4.7
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For Arduino IDE, download and install manually from: https://github.com/ESP32Async/AsyncTCP
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
5
33
|
## Connection Issues
|
|
6
34
|
|
|
7
35
|
### Nodes Not Connecting
|
|
@@ -153,6 +153,9 @@ class SensorPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
|
153
153
|
// Battery level percentage
|
|
154
154
|
uint8_t batteryLevel = 0;
|
|
155
155
|
|
|
156
|
+
// MQTT Schema v0.7.3+ message_type for faster classification
|
|
157
|
+
uint16_t messageType = 200; // SENSOR_DATA
|
|
158
|
+
|
|
156
159
|
// Type ID 200 for Alteriom sensors
|
|
157
160
|
SensorPackage() : BroadcastPackage(200) {}
|
|
158
161
|
|
|
@@ -163,6 +166,7 @@ class SensorPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
|
163
166
|
sensorId = jsonObj["sid"];
|
|
164
167
|
timestamp = jsonObj["ts"];
|
|
165
168
|
batteryLevel = jsonObj["bat"];
|
|
169
|
+
messageType = jsonObj["message_type"] | 200;
|
|
166
170
|
}
|
|
167
171
|
|
|
168
172
|
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
@@ -173,6 +177,7 @@ class SensorPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
|
173
177
|
jsonObj["sid"] = sensorId;
|
|
174
178
|
jsonObj["ts"] = timestamp;
|
|
175
179
|
jsonObj["bat"] = batteryLevel;
|
|
180
|
+
jsonObj["message_type"] = messageType;
|
|
176
181
|
return jsonObj;
|
|
177
182
|
}
|
|
178
183
|
|
|
@@ -193,14 +198,18 @@ class CommandPackage : public painlessmesh::plugin::SinglePackage {
|
|
|
193
198
|
TSTRING parameters = ""; // Command parameters as JSON string
|
|
194
199
|
uint32_t commandId = 0; // Unique command identifier for tracking
|
|
195
200
|
|
|
201
|
+
// MQTT Schema v0.7.3+ message_type for faster classification
|
|
202
|
+
uint16_t messageType = 400; // COMMAND
|
|
203
|
+
|
|
196
204
|
CommandPackage()
|
|
197
|
-
: SinglePackage(400) {} // Type ID 400 (COMMAND per mqtt-schema v0.7.
|
|
205
|
+
: SinglePackage(400) {} // Type ID 400 (COMMAND per mqtt-schema v0.7.3+)
|
|
198
206
|
|
|
199
207
|
CommandPackage(JsonObject jsonObj) : SinglePackage(jsonObj) {
|
|
200
208
|
command = jsonObj["cmd"];
|
|
201
209
|
targetDevice = jsonObj["target"];
|
|
202
210
|
parameters = jsonObj["params"].as<TSTRING>();
|
|
203
211
|
commandId = jsonObj["cid"];
|
|
212
|
+
messageType = jsonObj["message_type"] | 400;
|
|
204
213
|
}
|
|
205
214
|
|
|
206
215
|
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
@@ -209,6 +218,7 @@ class CommandPackage : public painlessmesh::plugin::SinglePackage {
|
|
|
209
218
|
jsonObj["target"] = targetDevice;
|
|
210
219
|
jsonObj["params"] = parameters;
|
|
211
220
|
jsonObj["cid"] = commandId;
|
|
221
|
+
jsonObj["message_type"] = messageType;
|
|
212
222
|
return jsonObj;
|
|
213
223
|
}
|
|
214
224
|
|
|
@@ -305,6 +315,9 @@ class StatusPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
|
305
315
|
float mqttBackoffMultiplier =
|
|
306
316
|
0.0; // Backoff multiplier for exponential backoff
|
|
307
317
|
|
|
318
|
+
// MQTT Schema v0.7.3+ message_type for faster classification
|
|
319
|
+
uint16_t messageType = 202; // SENSOR_STATUS
|
|
320
|
+
|
|
308
321
|
StatusPackage() : BroadcastPackage(202) {} // Type ID 202 for Alteriom status
|
|
309
322
|
|
|
310
323
|
StatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
@@ -378,6 +391,9 @@ class StatusPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
|
378
391
|
mqttMaxRetryMs = mqttRetry["max_retry_ms"] | 0;
|
|
379
392
|
mqttBackoffMultiplier = mqttRetry["backoff_multiplier"] | 0.0;
|
|
380
393
|
}
|
|
394
|
+
|
|
395
|
+
// Deserialize message_type field
|
|
396
|
+
messageType = jsonObj["message_type"] | 202;
|
|
381
397
|
}
|
|
382
398
|
|
|
383
399
|
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
@@ -451,6 +467,9 @@ class StatusPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
|
451
467
|
mqttRetry["max_retry_s"] = mqttMaxRetryMs / 1000;
|
|
452
468
|
mqttRetry["backoff_multiplier"] = mqttBackoffMultiplier;
|
|
453
469
|
|
|
470
|
+
// Serialize message_type field
|
|
471
|
+
jsonObj["message_type"] = messageType;
|
|
472
|
+
|
|
454
473
|
return jsonObj;
|
|
455
474
|
}
|
|
456
475
|
|
|
@@ -1146,6 +1165,219 @@ class MeshBridgePackage : public painlessmesh::plugin::BroadcastPackage {
|
|
|
1146
1165
|
#endif
|
|
1147
1166
|
};
|
|
1148
1167
|
|
|
1168
|
+
/**
|
|
1169
|
+
* @brief Bridge status package for monitoring Internet connectivity (Type 610
|
|
1170
|
+
* - BRIDGE_STATUS)
|
|
1171
|
+
*
|
|
1172
|
+
* This package is broadcast by bridge nodes to inform the mesh about their
|
|
1173
|
+
* Internet connectivity status. Regular nodes can use this information to
|
|
1174
|
+
* decide whether to send data, queue messages, or failover to backup bridges.
|
|
1175
|
+
*
|
|
1176
|
+
* Broadcast interval: Configurable, default 30 seconds
|
|
1177
|
+
* Timeout threshold: 60 seconds (nodes consider bridge offline if no heartbeat)
|
|
1178
|
+
*
|
|
1179
|
+
* Type ID 610 for BRIDGE_STATUS per mqtt-schema v0.7.3+.
|
|
1180
|
+
*/
|
|
1181
|
+
class BridgeStatusPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
1182
|
+
public:
|
|
1183
|
+
// Bridge connectivity status
|
|
1184
|
+
bool internetConnected = false; // Is the bridge connected to Internet?
|
|
1185
|
+
int8_t routerRSSI = 0; // Router WiFi signal strength in dBm
|
|
1186
|
+
uint8_t routerChannel = 0; // Router WiFi channel
|
|
1187
|
+
uint32_t uptime = 0; // Bridge uptime in milliseconds
|
|
1188
|
+
TSTRING gatewayIP = ""; // Router gateway IP address
|
|
1189
|
+
uint32_t timestamp = 0; // Timestamp of status check
|
|
1190
|
+
|
|
1191
|
+
// MQTT Schema v0.7.3+ message_type
|
|
1192
|
+
uint16_t messageType = 610; // BRIDGE_STATUS
|
|
1193
|
+
|
|
1194
|
+
BridgeStatusPackage() : BroadcastPackage(610) {}
|
|
1195
|
+
|
|
1196
|
+
BridgeStatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
1197
|
+
internetConnected = jsonObj["internetConnected"] | false;
|
|
1198
|
+
routerRSSI = jsonObj["routerRSSI"] | 0;
|
|
1199
|
+
routerChannel = jsonObj["routerChannel"] | 0;
|
|
1200
|
+
uptime = jsonObj["uptime"] | 0;
|
|
1201
|
+
gatewayIP = jsonObj["gatewayIP"].as<TSTRING>();
|
|
1202
|
+
timestamp = jsonObj["timestamp"] | 0;
|
|
1203
|
+
messageType = jsonObj["message_type"] | 610;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
1207
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
1208
|
+
jsonObj["internetConnected"] = internetConnected;
|
|
1209
|
+
jsonObj["routerRSSI"] = routerRSSI;
|
|
1210
|
+
jsonObj["routerChannel"] = routerChannel;
|
|
1211
|
+
jsonObj["uptime"] = uptime;
|
|
1212
|
+
jsonObj["gatewayIP"] = gatewayIP;
|
|
1213
|
+
jsonObj["timestamp"] = timestamp;
|
|
1214
|
+
jsonObj["message_type"] = messageType;
|
|
1215
|
+
return jsonObj;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
1219
|
+
size_t jsonObjectSize() const {
|
|
1220
|
+
return JSON_OBJECT_SIZE(noJsonFields + 7) + gatewayIP.length();
|
|
1221
|
+
}
|
|
1222
|
+
#endif
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* @brief Bridge election package for automatic failover (Type 611 -
|
|
1227
|
+
* BRIDGE_ELECTION)
|
|
1228
|
+
*
|
|
1229
|
+
* When a bridge node goes offline, regular nodes with router credentials can
|
|
1230
|
+
* participate in an election to become the new bridge. Each candidate
|
|
1231
|
+
* broadcasts its RSSI to the router, uptime, and available memory. The node
|
|
1232
|
+
* with the best RSSI wins the election.
|
|
1233
|
+
*
|
|
1234
|
+
* Election process:
|
|
1235
|
+
* 1. Bridge failure detected (no heartbeat for 60+ seconds)
|
|
1236
|
+
* 2. Nodes broadcast BridgeElectionPackage with their router RSSI
|
|
1237
|
+
* 3. 5-second collection window for all candidates
|
|
1238
|
+
* 4. Each node evaluates all candidates locally (deterministic)
|
|
1239
|
+
* 5. Winner promotes itself to bridge, others remain as regular nodes
|
|
1240
|
+
*
|
|
1241
|
+
* Type ID 611 for BRIDGE_ELECTION per mqtt-schema v0.7.3+.
|
|
1242
|
+
*/
|
|
1243
|
+
class BridgeElectionPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
1244
|
+
public:
|
|
1245
|
+
int8_t routerRSSI = 0; // Router WiFi signal strength in dBm (-127 to 0)
|
|
1246
|
+
uint32_t uptime = 0; // Node uptime in milliseconds
|
|
1247
|
+
uint32_t freeMemory = 0; // Free memory in bytes
|
|
1248
|
+
uint32_t timestamp = 0; // Election timestamp
|
|
1249
|
+
TSTRING routerSSID = ""; // Router SSID (for verification)
|
|
1250
|
+
|
|
1251
|
+
// MQTT Schema v0.7.3+ message_type
|
|
1252
|
+
uint16_t messageType = 611; // BRIDGE_ELECTION
|
|
1253
|
+
|
|
1254
|
+
BridgeElectionPackage() : BroadcastPackage(611) {}
|
|
1255
|
+
|
|
1256
|
+
BridgeElectionPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
1257
|
+
routerRSSI = jsonObj["routerRSSI"] | 0;
|
|
1258
|
+
uptime = jsonObj["uptime"] | 0;
|
|
1259
|
+
freeMemory = jsonObj["freeMemory"] | 0;
|
|
1260
|
+
timestamp = jsonObj["timestamp"] | 0;
|
|
1261
|
+
routerSSID = jsonObj["routerSSID"].as<TSTRING>();
|
|
1262
|
+
messageType = jsonObj["message_type"] | 611;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
1266
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
1267
|
+
jsonObj["routerRSSI"] = routerRSSI;
|
|
1268
|
+
jsonObj["uptime"] = uptime;
|
|
1269
|
+
jsonObj["freeMemory"] = freeMemory;
|
|
1270
|
+
jsonObj["timestamp"] = timestamp;
|
|
1271
|
+
jsonObj["routerSSID"] = routerSSID;
|
|
1272
|
+
jsonObj["message_type"] = messageType;
|
|
1273
|
+
return jsonObj;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
1277
|
+
size_t jsonObjectSize() const {
|
|
1278
|
+
return JSON_OBJECT_SIZE(noJsonFields + 6) + routerSSID.length();
|
|
1279
|
+
}
|
|
1280
|
+
#endif
|
|
1281
|
+
};
|
|
1282
|
+
|
|
1283
|
+
/**
|
|
1284
|
+
* @brief Bridge takeover announcement package (Type 612 - BRIDGE_TAKEOVER)
|
|
1285
|
+
*
|
|
1286
|
+
* After winning the bridge election, the new bridge node broadcasts this
|
|
1287
|
+
* package to inform all mesh nodes that it is now the primary bridge.
|
|
1288
|
+
* This allows nodes to update their bridge tracking and routing tables.
|
|
1289
|
+
*
|
|
1290
|
+
* Type ID 612 for BRIDGE_TAKEOVER per mqtt-schema v0.7.3+.
|
|
1291
|
+
*/
|
|
1292
|
+
class BridgeTakeoverPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
1293
|
+
public:
|
|
1294
|
+
uint32_t previousBridge = 0; // Previous bridge node ID (0 if none)
|
|
1295
|
+
TSTRING reason =
|
|
1296
|
+
""; // Reason for takeover (e.g., "Election winner - best router signal")
|
|
1297
|
+
int8_t routerRSSI = 0; // New bridge's router signal strength
|
|
1298
|
+
uint32_t timestamp = 0; // Takeover timestamp
|
|
1299
|
+
|
|
1300
|
+
// MQTT Schema v0.7.3+ message_type
|
|
1301
|
+
uint16_t messageType = 612; // BRIDGE_TAKEOVER
|
|
1302
|
+
|
|
1303
|
+
BridgeTakeoverPackage() : BroadcastPackage(612) {}
|
|
1304
|
+
|
|
1305
|
+
BridgeTakeoverPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
1306
|
+
previousBridge = jsonObj["previousBridge"] | 0;
|
|
1307
|
+
reason = jsonObj["reason"].as<TSTRING>();
|
|
1308
|
+
routerRSSI = jsonObj["routerRSSI"] | 0;
|
|
1309
|
+
timestamp = jsonObj["timestamp"] | 0;
|
|
1310
|
+
messageType = jsonObj["message_type"] | 612;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
1314
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
1315
|
+
jsonObj["previousBridge"] = previousBridge;
|
|
1316
|
+
jsonObj["reason"] = reason;
|
|
1317
|
+
jsonObj["routerRSSI"] = routerRSSI;
|
|
1318
|
+
jsonObj["timestamp"] = timestamp;
|
|
1319
|
+
jsonObj["message_type"] = messageType;
|
|
1320
|
+
return jsonObj;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
1324
|
+
size_t jsonObjectSize() const {
|
|
1325
|
+
return JSON_OBJECT_SIZE(noJsonFields + 5) + reason.length();
|
|
1326
|
+
}
|
|
1327
|
+
#endif
|
|
1328
|
+
};
|
|
1329
|
+
|
|
1330
|
+
/**
|
|
1331
|
+
* @brief NTP time synchronization package (Type 614 - TIME_SYNC_NTP)
|
|
1332
|
+
*
|
|
1333
|
+
* Broadcast by bridge nodes to distribute authoritative NTP time to the mesh.
|
|
1334
|
+
* When a bridge has Internet connectivity, it can provide NTP time to improve
|
|
1335
|
+
* accuracy across the entire mesh network.
|
|
1336
|
+
*
|
|
1337
|
+
* Regular nodes should:
|
|
1338
|
+
* 1. Accept time from bridge nodes (verify sender is bridge)
|
|
1339
|
+
* 2. Update local time with mesh.setTimeFromNTP(ntpTime)
|
|
1340
|
+
* 3. Optionally sync RTC modules if available
|
|
1341
|
+
*
|
|
1342
|
+
* Type ID 614 for TIME_SYNC_NTP.
|
|
1343
|
+
*/
|
|
1344
|
+
class NTPTimeSyncPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
1345
|
+
public:
|
|
1346
|
+
uint32_t ntpTime = 0; // Unix timestamp from NTP server
|
|
1347
|
+
uint16_t accuracy = 0; // Milliseconds uncertainty/precision
|
|
1348
|
+
TSTRING source = ""; // NTP server source (e.g., "pool.ntp.org")
|
|
1349
|
+
uint32_t timestamp = 0; // Collection timestamp
|
|
1350
|
+
|
|
1351
|
+
// MQTT Schema message_type
|
|
1352
|
+
uint16_t messageType = 614; // TIME_SYNC_NTP
|
|
1353
|
+
|
|
1354
|
+
NTPTimeSyncPackage() : BroadcastPackage(614) {}
|
|
1355
|
+
|
|
1356
|
+
NTPTimeSyncPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
1357
|
+
ntpTime = jsonObj["ntpTime"];
|
|
1358
|
+
accuracy = jsonObj["accuracy"];
|
|
1359
|
+
source = jsonObj["source"].as<TSTRING>();
|
|
1360
|
+
timestamp = jsonObj["timestamp"];
|
|
1361
|
+
messageType = jsonObj["message_type"] | 614;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
1365
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
1366
|
+
jsonObj["ntpTime"] = ntpTime;
|
|
1367
|
+
jsonObj["accuracy"] = accuracy;
|
|
1368
|
+
jsonObj["source"] = source;
|
|
1369
|
+
jsonObj["timestamp"] = timestamp;
|
|
1370
|
+
jsonObj["message_type"] = messageType;
|
|
1371
|
+
return jsonObj;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
1375
|
+
size_t jsonObjectSize() const {
|
|
1376
|
+
return JSON_OBJECT_SIZE(noJsonFields + 5) + source.length();
|
|
1377
|
+
}
|
|
1378
|
+
#endif
|
|
1379
|
+
};
|
|
1380
|
+
|
|
1149
1381
|
} // namespace alteriom
|
|
1150
1382
|
|
|
1151
1383
|
#endif // ALTERIOM_SENSOR_PACKAGE_HPP
|
|
@@ -14,7 +14,7 @@ framework = arduino
|
|
|
14
14
|
lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
|
|
15
15
|
lib_deps =
|
|
16
16
|
${env.lib_deps} ; Inherit common dependencies
|
|
17
|
-
esp32async/ESPAsyncTCP ; Only for ESP8266
|
|
17
|
+
esp32async/ESPAsyncTCP@^2.0.0 ; Only for ESP8266
|
|
18
18
|
|
|
19
19
|
[env:esp32]
|
|
20
20
|
platform = espressif32
|
|
@@ -20,7 +20,7 @@ framework = arduino
|
|
|
20
20
|
lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
|
|
21
21
|
lib_deps =
|
|
22
22
|
${env.lib_deps} ; Inherit common dependencies
|
|
23
|
-
esp32async/ESPAsyncTCP ; Only for ESP8266
|
|
23
|
+
esp32async/ESPAsyncTCP@^2.0.0 ; Only for ESP8266
|
|
24
24
|
|
|
25
25
|
[env:esp32]
|
|
26
26
|
platform = espressif32
|
|
@@ -116,7 +116,8 @@ void sendMetrics() {
|
|
|
116
116
|
// CPU and Processing
|
|
117
117
|
metrics.loopIterations = ((loopCount - lastLoopCount) * 1000) / timeDelta;
|
|
118
118
|
metrics.cpuUsage = calculateCPUUsage();
|
|
119
|
-
|
|
119
|
+
// Note: TaskScheduler doesn't provide a size() method, so we'll use 0 or estimate
|
|
120
|
+
metrics.taskQueueSize = 0; // TaskScheduler API doesn't expose queue size
|
|
120
121
|
|
|
121
122
|
// Memory Metrics
|
|
122
123
|
metrics.freeHeap = ESP.getFreeHeap();
|
|
@@ -155,8 +156,13 @@ void sendMetrics() {
|
|
|
155
156
|
metrics.collectionTimestamp = mesh.getNodeTime();
|
|
156
157
|
metrics.collectionInterval = METRICS_INTERVAL;
|
|
157
158
|
|
|
158
|
-
//
|
|
159
|
-
|
|
159
|
+
// Serialize and send the metrics
|
|
160
|
+
JsonDocument doc;
|
|
161
|
+
JsonObject obj = doc.to<JsonObject>();
|
|
162
|
+
metrics.addTo(std::move(obj));
|
|
163
|
+
|
|
164
|
+
String msg;
|
|
165
|
+
serializeJson(doc, msg);
|
|
160
166
|
bool sent = mesh.sendBroadcast(msg);
|
|
161
167
|
|
|
162
168
|
if (sent) {
|
|
@@ -266,8 +272,13 @@ void sendHealthCheck() {
|
|
|
266
272
|
health.checkTimestamp = mesh.getNodeTime();
|
|
267
273
|
health.nextCheckDue = health.checkTimestamp + (HEALTH_INTERVAL * 1000);
|
|
268
274
|
|
|
269
|
-
//
|
|
270
|
-
|
|
275
|
+
// Serialize and send the health check
|
|
276
|
+
JsonDocument doc;
|
|
277
|
+
JsonObject obj = doc.to<JsonObject>();
|
|
278
|
+
health.addTo(std::move(obj));
|
|
279
|
+
|
|
280
|
+
String msg;
|
|
281
|
+
serializeJson(doc, msg);
|
|
271
282
|
bool sent = mesh.sendBroadcast(msg);
|
|
272
283
|
|
|
273
284
|
if (sent) {
|
|
@@ -372,10 +383,10 @@ void receivedCallback(uint32_t from, String& msg) {
|
|
|
372
383
|
totalPacketsRx++;
|
|
373
384
|
|
|
374
385
|
// Parse message type
|
|
375
|
-
|
|
386
|
+
JsonDocument doc;
|
|
376
387
|
deserializeJson(doc, msg);
|
|
377
388
|
JsonObject obj = doc.as<JsonObject>();
|
|
378
|
-
|
|
389
|
+
uint16_t msgType = obj["type"];
|
|
379
390
|
|
|
380
391
|
Serial.printf("\nReceived Type %d from %u\n", msgType, from);
|
|
381
392
|
|
|
@@ -14,7 +14,7 @@ framework = arduino
|
|
|
14
14
|
lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
|
|
15
15
|
lib_deps =
|
|
16
16
|
${env.lib_deps} ; Inherit common dependencies
|
|
17
|
-
esp32async/ESPAsyncTCP ; Only for ESP8266
|
|
17
|
+
esp32async/ESPAsyncTCP@^2.0.0 ; Only for ESP8266
|
|
18
18
|
|
|
19
19
|
[env:esp32]
|
|
20
20
|
platform = espressif32
|
|
@@ -14,7 +14,7 @@ framework = arduino
|
|
|
14
14
|
lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
|
|
15
15
|
lib_deps =
|
|
16
16
|
${env.lib_deps} ; Inherit common dependencies
|
|
17
|
-
esp32async/ESPAsyncTCP ; Only for ESP8266
|
|
17
|
+
esp32async/ESPAsyncTCP@^2.0.0 ; Only for ESP8266
|
|
18
18
|
|
|
19
19
|
[env:esp32]
|
|
20
20
|
platform = espressif32
|
|
@@ -14,7 +14,7 @@ framework = arduino
|
|
|
14
14
|
lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
|
|
15
15
|
lib_deps =
|
|
16
16
|
${env.lib_deps} ; Inherit common dependencies
|
|
17
|
-
esp32async/ESPAsyncTCP ; Only for ESP8266
|
|
17
|
+
esp32async/ESPAsyncTCP@^2.0.0 ; Only for ESP8266
|
|
18
18
|
|
|
19
19
|
[env:esp32]
|
|
20
20
|
platform = espressif32
|