@alteriom/painlessmesh 1.7.6 → 1.7.8
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 +177 -0
- package/README.md +96 -14
- package/RELEASE_GUIDE.md +36 -0
- package/docs/API_DESIGN_GUIDELINES.md +414 -0
- package/docs/BOOLEAN_NAMING_CONVENTION.md +235 -0
- package/docs/MQTT_BRIDGE_COMMANDS.md +10 -10
- package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +1 -1
- package/docs/MQTT_SCHEMA_COMPLIANCE.md +57 -2
- package/docs/PHASE1_GUIDE.md +1 -1
- package/docs/alteriom/overview.md +25 -2
- package/docs/architecture/plugin-system.md +1 -1
- package/docs/archive/RELEASE_SUMMARY.md +1 -1
- package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +389 -0
- package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +391 -0
- package/docs/v1.7.7_MQTT_IMPROVEMENTS.md +794 -0
- package/docs/wiki/API-Reference.md +2 -2
- package/docs/wiki/Complete-Documentation.md +1 -1
- package/examples/alteriom/README.md +150 -4
- package/examples/alteriom/alteriom.ino +1 -1
- package/examples/alteriom/alteriom_sensor_package.hpp +914 -4
- package/examples/alteriomImproved/alteriom_sensor_package.hpp +1 -1
- package/examples/alteriomImproved/improved_sensor_node.ino +1 -1
- package/examples/alteriomMetricsHealth/alteriom_sensor_package.hpp +796 -0
- package/examples/alteriomMetricsHealth/metrics_health_node.ino +418 -0
- package/examples/alteriomMetricsHealth/platformio.ini +26 -0
- package/examples/alteriomPhase1/alteriom_sensor_package.hpp +1 -1
- package/examples/alteriomPhase1/phase1_features.ino +2 -2
- package/examples/alteriomPhase2/alteriom_sensor_package.hpp +1 -1
- package/examples/alteriomSensorNode/alteriom_sensor_node.ino +1 -1
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +1 -1
- package/examples/bridge/enhanced_mqtt_bridge.hpp +610 -0
- package/examples/bridge/enhanced_mqtt_bridge_example.ino +226 -0
- package/examples/meshCommandNode/alteriom_sensor_package.hpp +1 -1
- package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +1 -1
- package/examples/mqttTopologyTest/mqttTopologyTest.ino +5 -1
- package/library.json +1 -1
- package/library.properties +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,796 @@
|
|
|
1
|
+
#ifndef ALTERIOM_SENSOR_PACKAGE_HPP
|
|
2
|
+
#define ALTERIOM_SENSOR_PACKAGE_HPP
|
|
3
|
+
|
|
4
|
+
#include "painlessmesh/plugin.hpp"
|
|
5
|
+
|
|
6
|
+
namespace alteriom {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @brief Sensor data package for broadcasting environmental measurements
|
|
10
|
+
*
|
|
11
|
+
* This package is designed for Alteriom's IoT sensor network requirements,
|
|
12
|
+
* allowing nodes to share environmental data across the mesh.
|
|
13
|
+
*/
|
|
14
|
+
class SensorPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
15
|
+
public:
|
|
16
|
+
// Temperature in Celsius
|
|
17
|
+
double temperature = 0.0;
|
|
18
|
+
// Relative humidity percentage
|
|
19
|
+
double humidity = 0.0;
|
|
20
|
+
// Atmospheric pressure in hPa
|
|
21
|
+
double pressure = 0.0;
|
|
22
|
+
// Unique sensor identifier
|
|
23
|
+
uint32_t sensorId = 0;
|
|
24
|
+
// Unix timestamp of measurement
|
|
25
|
+
uint32_t timestamp = 0;
|
|
26
|
+
// Battery level percentage
|
|
27
|
+
uint8_t batteryLevel = 0;
|
|
28
|
+
|
|
29
|
+
// Type ID 200 for Alteriom sensors
|
|
30
|
+
SensorPackage() : BroadcastPackage(200) {}
|
|
31
|
+
|
|
32
|
+
SensorPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
33
|
+
temperature = jsonObj["temp"];
|
|
34
|
+
humidity = jsonObj["hum"];
|
|
35
|
+
pressure = jsonObj["press"];
|
|
36
|
+
sensorId = jsonObj["sid"];
|
|
37
|
+
timestamp = jsonObj["ts"];
|
|
38
|
+
batteryLevel = jsonObj["bat"];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
42
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
43
|
+
jsonObj["temp"] = temperature;
|
|
44
|
+
jsonObj["hum"] = humidity;
|
|
45
|
+
jsonObj["press"] = pressure;
|
|
46
|
+
jsonObj["sid"] = sensorId;
|
|
47
|
+
jsonObj["ts"] = timestamp;
|
|
48
|
+
jsonObj["bat"] = batteryLevel;
|
|
49
|
+
return jsonObj;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
53
|
+
size_t jsonObjectSize() const { return JSON_OBJECT_SIZE(noJsonFields + 6); }
|
|
54
|
+
#endif
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @brief Command package for controlling Alteriom devices
|
|
59
|
+
*
|
|
60
|
+
* Single-destination package for sending specific commands to individual nodes.
|
|
61
|
+
*/
|
|
62
|
+
class CommandPackage : public painlessmesh::plugin::SinglePackage {
|
|
63
|
+
public:
|
|
64
|
+
uint8_t command = 0; // Command type
|
|
65
|
+
uint32_t targetDevice = 0; // Target device ID
|
|
66
|
+
TSTRING parameters = ""; // Command parameters as JSON string
|
|
67
|
+
uint32_t commandId = 0; // Unique command identifier for tracking
|
|
68
|
+
|
|
69
|
+
CommandPackage()
|
|
70
|
+
: SinglePackage(400) {} // Type ID 400 (COMMAND per mqtt-schema v0.7.2+)
|
|
71
|
+
|
|
72
|
+
CommandPackage(JsonObject jsonObj) : SinglePackage(jsonObj) {
|
|
73
|
+
command = jsonObj["cmd"];
|
|
74
|
+
targetDevice = jsonObj["target"];
|
|
75
|
+
parameters = jsonObj["params"].as<TSTRING>();
|
|
76
|
+
commandId = jsonObj["cid"];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
80
|
+
jsonObj = SinglePackage::addTo(std::move(jsonObj));
|
|
81
|
+
jsonObj["cmd"] = command;
|
|
82
|
+
jsonObj["target"] = targetDevice;
|
|
83
|
+
jsonObj["params"] = parameters;
|
|
84
|
+
jsonObj["cid"] = commandId;
|
|
85
|
+
return jsonObj;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
89
|
+
size_t jsonObjectSize() const {
|
|
90
|
+
return JSON_OBJECT_SIZE(noJsonFields + 4) + parameters.length();
|
|
91
|
+
}
|
|
92
|
+
#endif
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @brief Status report package for device health monitoring
|
|
97
|
+
*/
|
|
98
|
+
class StatusPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
99
|
+
public:
|
|
100
|
+
uint8_t deviceStatus = 0; // Device status flags
|
|
101
|
+
uint32_t uptime = 0; // Device uptime in seconds
|
|
102
|
+
uint16_t freeMemory = 0; // Free memory in KB
|
|
103
|
+
uint8_t wifiStrength = 0; // WiFi signal strength
|
|
104
|
+
TSTRING firmwareVersion = ""; // Current firmware version
|
|
105
|
+
|
|
106
|
+
// Command response fields (for MQTT bridge)
|
|
107
|
+
uint32_t responseToCommand = 0; // CommandId this is responding to
|
|
108
|
+
TSTRING responseMessage = ""; // Success/error message
|
|
109
|
+
|
|
110
|
+
StatusPackage() : BroadcastPackage(202) {} // Type ID 202 for Alteriom status
|
|
111
|
+
|
|
112
|
+
StatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
113
|
+
deviceStatus = jsonObj["status"];
|
|
114
|
+
uptime = jsonObj["uptime"];
|
|
115
|
+
freeMemory = jsonObj["mem"];
|
|
116
|
+
wifiStrength = jsonObj["wifi"];
|
|
117
|
+
firmwareVersion = jsonObj["fw"].as<TSTRING>();
|
|
118
|
+
responseToCommand = jsonObj["respTo"] | 0;
|
|
119
|
+
responseMessage = jsonObj["respMsg"].as<TSTRING>();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
123
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
124
|
+
jsonObj["status"] = deviceStatus;
|
|
125
|
+
jsonObj["uptime"] = uptime;
|
|
126
|
+
jsonObj["mem"] = freeMemory;
|
|
127
|
+
jsonObj["wifi"] = wifiStrength;
|
|
128
|
+
jsonObj["fw"] = firmwareVersion;
|
|
129
|
+
if (responseToCommand > 0) {
|
|
130
|
+
jsonObj["respTo"] = responseToCommand;
|
|
131
|
+
jsonObj["respMsg"] = responseMessage;
|
|
132
|
+
}
|
|
133
|
+
return jsonObj;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
137
|
+
size_t jsonObjectSize() const {
|
|
138
|
+
return JSON_OBJECT_SIZE(noJsonFields + 7) + firmwareVersion.length() +
|
|
139
|
+
responseMessage.length();
|
|
140
|
+
}
|
|
141
|
+
#endif
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @brief Enhanced status package with comprehensive health metrics (Phase 1)
|
|
146
|
+
*
|
|
147
|
+
* This is an extended version of StatusPackage that includes additional
|
|
148
|
+
* mesh statistics, performance metrics, and alerting capabilities.
|
|
149
|
+
* Type ID 203 is used to distinguish from the basic StatusPackage (202).
|
|
150
|
+
*/
|
|
151
|
+
class EnhancedStatusPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
152
|
+
public:
|
|
153
|
+
// Device Health (from original StatusPackage)
|
|
154
|
+
uint8_t deviceStatus = 0; // Device status flags
|
|
155
|
+
uint32_t uptime = 0; // Device uptime in seconds
|
|
156
|
+
uint16_t freeMemory = 0; // Free memory in KB
|
|
157
|
+
uint8_t wifiStrength = 0; // WiFi signal strength
|
|
158
|
+
TSTRING firmwareVersion = ""; // Current firmware version
|
|
159
|
+
TSTRING firmwareMD5 = ""; // Firmware hash for OTA verification
|
|
160
|
+
|
|
161
|
+
// Mesh Statistics
|
|
162
|
+
uint16_t nodeCount = 0; // Number of known nodes in mesh
|
|
163
|
+
uint8_t connectionCount = 0; // Number of direct connections
|
|
164
|
+
uint32_t messagesReceived = 0; // Total messages received
|
|
165
|
+
uint32_t messagesSent = 0; // Total messages sent
|
|
166
|
+
uint32_t messagesDropped = 0; // Total messages dropped/failed
|
|
167
|
+
|
|
168
|
+
// Performance Metrics
|
|
169
|
+
uint16_t avgLatency = 0; // Average message latency in ms
|
|
170
|
+
uint8_t packetLossRate = 0; // Packet loss rate percentage (0-100)
|
|
171
|
+
uint16_t throughput = 0; // Network throughput in bytes/sec
|
|
172
|
+
|
|
173
|
+
// Warnings/Alerts
|
|
174
|
+
uint8_t alertFlags = 0; // Bit flags for various alert conditions
|
|
175
|
+
TSTRING lastError = ""; // Last error message for diagnostics
|
|
176
|
+
|
|
177
|
+
EnhancedStatusPackage()
|
|
178
|
+
: BroadcastPackage(604) {
|
|
179
|
+
} // Type ID 604 for enhanced status (MESH_STATUS per mqtt-schema v0.7.2+)
|
|
180
|
+
|
|
181
|
+
EnhancedStatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
182
|
+
deviceStatus = jsonObj["status"];
|
|
183
|
+
uptime = jsonObj["uptime"];
|
|
184
|
+
freeMemory = jsonObj["mem"];
|
|
185
|
+
wifiStrength = jsonObj["wifi"];
|
|
186
|
+
firmwareVersion = jsonObj["fw"].as<TSTRING>();
|
|
187
|
+
firmwareMD5 = jsonObj["fwMD5"].as<TSTRING>();
|
|
188
|
+
|
|
189
|
+
nodeCount = jsonObj["nodes"];
|
|
190
|
+
connectionCount = jsonObj["conns"];
|
|
191
|
+
messagesReceived = jsonObj["msgRx"];
|
|
192
|
+
messagesSent = jsonObj["msgTx"];
|
|
193
|
+
messagesDropped = jsonObj["msgDrop"];
|
|
194
|
+
|
|
195
|
+
avgLatency = jsonObj["latency"];
|
|
196
|
+
packetLossRate = jsonObj["loss"];
|
|
197
|
+
throughput = jsonObj["throughput"];
|
|
198
|
+
|
|
199
|
+
alertFlags = jsonObj["alerts"];
|
|
200
|
+
lastError = jsonObj["lastErr"].as<TSTRING>();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
204
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
205
|
+
|
|
206
|
+
// Device Health
|
|
207
|
+
jsonObj["status"] = deviceStatus;
|
|
208
|
+
jsonObj["uptime"] = uptime;
|
|
209
|
+
jsonObj["mem"] = freeMemory;
|
|
210
|
+
jsonObj["wifi"] = wifiStrength;
|
|
211
|
+
jsonObj["fw"] = firmwareVersion;
|
|
212
|
+
jsonObj["fwMD5"] = firmwareMD5;
|
|
213
|
+
|
|
214
|
+
// Mesh Statistics
|
|
215
|
+
jsonObj["nodes"] = nodeCount;
|
|
216
|
+
jsonObj["conns"] = connectionCount;
|
|
217
|
+
jsonObj["msgRx"] = messagesReceived;
|
|
218
|
+
jsonObj["msgTx"] = messagesSent;
|
|
219
|
+
jsonObj["msgDrop"] = messagesDropped;
|
|
220
|
+
|
|
221
|
+
// Performance Metrics
|
|
222
|
+
jsonObj["latency"] = avgLatency;
|
|
223
|
+
jsonObj["loss"] = packetLossRate;
|
|
224
|
+
jsonObj["throughput"] = throughput;
|
|
225
|
+
|
|
226
|
+
// Alerts
|
|
227
|
+
jsonObj["alerts"] = alertFlags;
|
|
228
|
+
jsonObj["lastErr"] = lastError;
|
|
229
|
+
|
|
230
|
+
return jsonObj;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
234
|
+
size_t jsonObjectSize() const {
|
|
235
|
+
return JSON_OBJECT_SIZE(noJsonFields + 18) + firmwareVersion.length() +
|
|
236
|
+
firmwareMD5.length() + lastError.length();
|
|
237
|
+
}
|
|
238
|
+
#endif
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @brief Detailed performance metrics package for monitoring (Phase 2)
|
|
243
|
+
*
|
|
244
|
+
* Provides comprehensive performance data including CPU usage, memory trends,
|
|
245
|
+
* network throughput, and other metrics useful for dashboards and monitoring.
|
|
246
|
+
* Type ID 204 for Alteriom metrics.
|
|
247
|
+
*/
|
|
248
|
+
class MetricsPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
249
|
+
public:
|
|
250
|
+
// CPU and Processing
|
|
251
|
+
uint8_t cpuUsage = 0; // CPU usage percentage (0-100)
|
|
252
|
+
uint32_t loopIterations = 0; // Loop iterations per second
|
|
253
|
+
uint16_t taskQueueSize = 0; // Number of pending tasks
|
|
254
|
+
|
|
255
|
+
// Memory Metrics
|
|
256
|
+
uint32_t freeHeap = 0; // Free heap memory in bytes
|
|
257
|
+
uint32_t minFreeHeap = 0; // Minimum free heap since boot
|
|
258
|
+
uint32_t heapFragmentation = 0; // Heap fragmentation percentage
|
|
259
|
+
uint32_t maxAllocHeap = 0; // Largest allocatable block
|
|
260
|
+
|
|
261
|
+
// Network Performance
|
|
262
|
+
uint32_t bytesReceived = 0; // Total bytes received
|
|
263
|
+
uint32_t bytesSent = 0; // Total bytes sent
|
|
264
|
+
uint16_t packetsReceived = 0; // Total packets received
|
|
265
|
+
uint16_t packetsSent = 0; // Total packets sent
|
|
266
|
+
uint16_t packetsDropped = 0; // Packets dropped
|
|
267
|
+
uint16_t currentThroughput = 0; // Current throughput in bytes/sec
|
|
268
|
+
|
|
269
|
+
// Timing and Latency
|
|
270
|
+
uint32_t avgResponseTime = 0; // Average response time in microseconds
|
|
271
|
+
uint32_t maxResponseTime = 0; // Maximum response time in microseconds
|
|
272
|
+
uint16_t avgMeshLatency = 0; // Average mesh latency in milliseconds
|
|
273
|
+
|
|
274
|
+
// Connection Quality
|
|
275
|
+
uint8_t connectionQuality = 0; // Overall connection quality (0-100)
|
|
276
|
+
int8_t wifiRSSI = 0; // WiFi RSSI in dBm
|
|
277
|
+
|
|
278
|
+
// Collection metadata
|
|
279
|
+
uint32_t collectionTimestamp = 0; // When metrics were collected
|
|
280
|
+
uint32_t collectionInterval = 0; // Interval between collections in ms
|
|
281
|
+
|
|
282
|
+
// MQTT Schema v0.7.2+ message_type for faster classification
|
|
283
|
+
uint16_t messageType = 204; // SENSOR_METRICS (aligns with schema v0.7.2+)
|
|
284
|
+
|
|
285
|
+
MetricsPackage() : BroadcastPackage(204) {}
|
|
286
|
+
|
|
287
|
+
MetricsPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
288
|
+
cpuUsage = jsonObj["cpu"];
|
|
289
|
+
loopIterations = jsonObj["loops"];
|
|
290
|
+
taskQueueSize = jsonObj["tasks"];
|
|
291
|
+
|
|
292
|
+
freeHeap = jsonObj["heap"];
|
|
293
|
+
minFreeHeap = jsonObj["minHeap"];
|
|
294
|
+
heapFragmentation = jsonObj["fragHeap"];
|
|
295
|
+
maxAllocHeap = jsonObj["maxHeap"];
|
|
296
|
+
|
|
297
|
+
bytesReceived = jsonObj["bytesRx"];
|
|
298
|
+
bytesSent = jsonObj["bytesTx"];
|
|
299
|
+
packetsReceived = jsonObj["pktsRx"];
|
|
300
|
+
packetsSent = jsonObj["pktsTx"];
|
|
301
|
+
packetsDropped = jsonObj["pktsDrop"];
|
|
302
|
+
currentThroughput = jsonObj["throughput"];
|
|
303
|
+
|
|
304
|
+
avgResponseTime = jsonObj["avgResp"];
|
|
305
|
+
maxResponseTime = jsonObj["maxResp"];
|
|
306
|
+
avgMeshLatency = jsonObj["avgLat"];
|
|
307
|
+
|
|
308
|
+
connectionQuality = jsonObj["connQual"];
|
|
309
|
+
wifiRSSI = jsonObj["rssi"];
|
|
310
|
+
|
|
311
|
+
collectionTimestamp = jsonObj["ts"];
|
|
312
|
+
collectionInterval = jsonObj["interval"];
|
|
313
|
+
messageType = jsonObj["message_type"] | 204;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
317
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
318
|
+
|
|
319
|
+
// CPU and Processing
|
|
320
|
+
jsonObj["cpu"] = cpuUsage;
|
|
321
|
+
jsonObj["loops"] = loopIterations;
|
|
322
|
+
jsonObj["tasks"] = taskQueueSize;
|
|
323
|
+
|
|
324
|
+
// Memory Metrics
|
|
325
|
+
jsonObj["heap"] = freeHeap;
|
|
326
|
+
jsonObj["minHeap"] = minFreeHeap;
|
|
327
|
+
jsonObj["fragHeap"] = heapFragmentation;
|
|
328
|
+
jsonObj["maxHeap"] = maxAllocHeap;
|
|
329
|
+
|
|
330
|
+
// Network Performance
|
|
331
|
+
jsonObj["bytesRx"] = bytesReceived;
|
|
332
|
+
jsonObj["bytesTx"] = bytesSent;
|
|
333
|
+
jsonObj["pktsRx"] = packetsReceived;
|
|
334
|
+
jsonObj["pktsTx"] = packetsSent;
|
|
335
|
+
jsonObj["pktsDrop"] = packetsDropped;
|
|
336
|
+
jsonObj["throughput"] = currentThroughput;
|
|
337
|
+
|
|
338
|
+
// Timing and Latency
|
|
339
|
+
jsonObj["avgResp"] = avgResponseTime;
|
|
340
|
+
jsonObj["maxResp"] = maxResponseTime;
|
|
341
|
+
jsonObj["avgLat"] = avgMeshLatency;
|
|
342
|
+
|
|
343
|
+
// Connection Quality
|
|
344
|
+
jsonObj["connQual"] = connectionQuality;
|
|
345
|
+
jsonObj["rssi"] = wifiRSSI;
|
|
346
|
+
|
|
347
|
+
// Metadata
|
|
348
|
+
jsonObj["ts"] = collectionTimestamp;
|
|
349
|
+
jsonObj["interval"] = collectionInterval;
|
|
350
|
+
jsonObj["message_type"] = messageType; // MQTT Schema v0.7.1+
|
|
351
|
+
|
|
352
|
+
return jsonObj;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
356
|
+
size_t jsonObjectSize() const { return JSON_OBJECT_SIZE(noJsonFields + 22); }
|
|
357
|
+
#endif
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* @brief Health check package for proactive problem detection (Phase 2)
|
|
362
|
+
*
|
|
363
|
+
* Provides early warning indicators and health status to detect issues
|
|
364
|
+
* before they cause failures. Used for predictive maintenance and alerting.
|
|
365
|
+
* Type ID 605 for Alteriom health checks (MESH_METRICS per mqtt-schema
|
|
366
|
+
* v0.7.2+).
|
|
367
|
+
*/
|
|
368
|
+
class HealthCheckPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
369
|
+
public:
|
|
370
|
+
// Overall Health Status (0=critical, 1=warning, 2=healthy)
|
|
371
|
+
uint8_t healthStatus = 2;
|
|
372
|
+
|
|
373
|
+
// Problem Indicators (bit flags)
|
|
374
|
+
uint16_t problemFlags = 0; // Bit flags for specific problems
|
|
375
|
+
/*
|
|
376
|
+
* Problem flag bits:
|
|
377
|
+
* 0x0001 - Low memory warning
|
|
378
|
+
* 0x0002 - High CPU usage
|
|
379
|
+
* 0x0004 - Connection instability
|
|
380
|
+
* 0x0008 - High packet loss
|
|
381
|
+
* 0x0010 - Network congestion
|
|
382
|
+
* 0x0020 - Low battery (if applicable)
|
|
383
|
+
* 0x0040 - Thermal warning
|
|
384
|
+
* 0x0080 - Mesh partition detected
|
|
385
|
+
* 0x0100 - OTA in progress
|
|
386
|
+
* 0x0200 - Configuration error
|
|
387
|
+
*/
|
|
388
|
+
|
|
389
|
+
// Memory Health
|
|
390
|
+
uint8_t memoryHealth = 100; // Memory health score (0-100)
|
|
391
|
+
uint32_t memoryTrend = 0; // Bytes/hour memory loss (for leak detection)
|
|
392
|
+
|
|
393
|
+
// Network Health
|
|
394
|
+
uint8_t networkHealth = 100; // Network health score (0-100)
|
|
395
|
+
uint8_t packetLossPercent = 0; // Packet loss percentage
|
|
396
|
+
uint8_t reconnectionCount = 0; // Reconnections in last hour
|
|
397
|
+
|
|
398
|
+
// Performance Health
|
|
399
|
+
uint8_t performanceHealth = 100; // Performance health score (0-100)
|
|
400
|
+
uint32_t missedDeadlines = 0; // Missed task deadlines
|
|
401
|
+
uint16_t maxLoopTime = 0; // Maximum loop execution time in ms
|
|
402
|
+
|
|
403
|
+
// Environmental (if sensors available)
|
|
404
|
+
int8_t temperature = 0; // Device temperature in Celsius
|
|
405
|
+
uint8_t temperatureHealth = 100; // Temperature health score
|
|
406
|
+
|
|
407
|
+
// Uptime and Stability
|
|
408
|
+
uint32_t uptime = 0; // Uptime in seconds
|
|
409
|
+
uint16_t crashCount = 0; // Crash/restart count
|
|
410
|
+
uint32_t lastRebootReason = 0; // Last reboot reason code
|
|
411
|
+
|
|
412
|
+
// Predictive indicators
|
|
413
|
+
uint16_t estimatedTimeToFailure =
|
|
414
|
+
0; // Estimated hours until failure (0=unknown)
|
|
415
|
+
TSTRING recommendations = ""; // Recommended actions
|
|
416
|
+
|
|
417
|
+
// Check metadata
|
|
418
|
+
uint32_t checkTimestamp = 0; // When check was performed
|
|
419
|
+
uint32_t nextCheckDue = 0; // When next check is due
|
|
420
|
+
|
|
421
|
+
// MQTT Schema v0.7.2+ message_type for faster classification
|
|
422
|
+
uint16_t messageType = 605; // MESH_METRICS type code (mesh performance
|
|
423
|
+
// health per mqtt-schema v0.7.2+)
|
|
424
|
+
|
|
425
|
+
HealthCheckPackage() : BroadcastPackage(605) {}
|
|
426
|
+
|
|
427
|
+
HealthCheckPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
428
|
+
healthStatus = jsonObj["health"];
|
|
429
|
+
problemFlags = jsonObj["problems"];
|
|
430
|
+
|
|
431
|
+
memoryHealth = jsonObj["memHealth"];
|
|
432
|
+
memoryTrend = jsonObj["memTrend"];
|
|
433
|
+
|
|
434
|
+
networkHealth = jsonObj["netHealth"];
|
|
435
|
+
packetLossPercent = jsonObj["loss"];
|
|
436
|
+
reconnectionCount = jsonObj["reconn"];
|
|
437
|
+
|
|
438
|
+
performanceHealth = jsonObj["perfHealth"];
|
|
439
|
+
missedDeadlines = jsonObj["missed"];
|
|
440
|
+
maxLoopTime = jsonObj["maxLoop"];
|
|
441
|
+
|
|
442
|
+
temperature = jsonObj["temp"];
|
|
443
|
+
temperatureHealth = jsonObj["tempHealth"];
|
|
444
|
+
|
|
445
|
+
uptime = jsonObj["uptime"];
|
|
446
|
+
crashCount = jsonObj["crashes"];
|
|
447
|
+
lastRebootReason = jsonObj["reboot"];
|
|
448
|
+
|
|
449
|
+
estimatedTimeToFailure = jsonObj["ettf"];
|
|
450
|
+
recommendations = jsonObj["recommend"].as<TSTRING>();
|
|
451
|
+
|
|
452
|
+
checkTimestamp = jsonObj["ts"];
|
|
453
|
+
nextCheckDue = jsonObj["nextCheck"];
|
|
454
|
+
messageType = jsonObj["message_type"] | 605;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
458
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
459
|
+
|
|
460
|
+
jsonObj["health"] = healthStatus;
|
|
461
|
+
jsonObj["problems"] = problemFlags;
|
|
462
|
+
|
|
463
|
+
jsonObj["memHealth"] = memoryHealth;
|
|
464
|
+
jsonObj["memTrend"] = memoryTrend;
|
|
465
|
+
|
|
466
|
+
jsonObj["netHealth"] = networkHealth;
|
|
467
|
+
jsonObj["loss"] = packetLossPercent;
|
|
468
|
+
jsonObj["reconn"] = reconnectionCount;
|
|
469
|
+
|
|
470
|
+
jsonObj["perfHealth"] = performanceHealth;
|
|
471
|
+
jsonObj["missed"] = missedDeadlines;
|
|
472
|
+
jsonObj["maxLoop"] = maxLoopTime;
|
|
473
|
+
|
|
474
|
+
jsonObj["temp"] = temperature;
|
|
475
|
+
jsonObj["tempHealth"] = temperatureHealth;
|
|
476
|
+
|
|
477
|
+
jsonObj["uptime"] = uptime;
|
|
478
|
+
jsonObj["crashes"] = crashCount;
|
|
479
|
+
jsonObj["reboot"] = lastRebootReason;
|
|
480
|
+
|
|
481
|
+
jsonObj["ettf"] = estimatedTimeToFailure;
|
|
482
|
+
jsonObj["recommend"] = recommendations;
|
|
483
|
+
|
|
484
|
+
jsonObj["ts"] = checkTimestamp;
|
|
485
|
+
jsonObj["nextCheck"] = nextCheckDue;
|
|
486
|
+
jsonObj["message_type"] = messageType; // MQTT Schema v0.7.1+
|
|
487
|
+
|
|
488
|
+
return jsonObj;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
492
|
+
size_t jsonObjectSize() const {
|
|
493
|
+
return JSON_OBJECT_SIZE(noJsonFields + 20) + recommendations.length();
|
|
494
|
+
}
|
|
495
|
+
#endif
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @brief Mesh node information for a single node
|
|
500
|
+
*/
|
|
501
|
+
struct MeshNodeInfo {
|
|
502
|
+
uint32_t nodeId = 0; // Node identifier
|
|
503
|
+
uint8_t status = 0; // 0=offline, 1=online, 2=unreachable
|
|
504
|
+
uint32_t lastSeen = 0; // Unix timestamp of last communication
|
|
505
|
+
int8_t signalStrength = 0; // RSSI in dBm
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* @brief Mesh node list package (Type 600 - MESH_NODE_LIST)
|
|
510
|
+
*
|
|
511
|
+
* Provides list of all nodes in the mesh network with their status.
|
|
512
|
+
* Type ID 600 for MESH_NODE_LIST per mqtt-schema v0.7.2+.
|
|
513
|
+
*/
|
|
514
|
+
class MeshNodeListPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
515
|
+
public:
|
|
516
|
+
// Array of node information (max 50 nodes)
|
|
517
|
+
MeshNodeInfo nodes[50];
|
|
518
|
+
uint8_t nodeCount = 0; // Actual number of nodes
|
|
519
|
+
TSTRING meshId = ""; // Mesh network identifier
|
|
520
|
+
|
|
521
|
+
// MQTT Schema v0.7.2+ message_type
|
|
522
|
+
uint16_t messageType = 600; // MESH_NODE_LIST
|
|
523
|
+
|
|
524
|
+
MeshNodeListPackage() : BroadcastPackage(600) {}
|
|
525
|
+
|
|
526
|
+
MeshNodeListPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
527
|
+
JsonArray nodesArray = jsonObj["nodes"];
|
|
528
|
+
nodeCount = nodesArray.size();
|
|
529
|
+
if (nodeCount > 50) nodeCount = 50;
|
|
530
|
+
|
|
531
|
+
for (uint8_t i = 0; i < nodeCount; i++) {
|
|
532
|
+
JsonObject node = nodesArray[i];
|
|
533
|
+
nodes[i].nodeId = node["nodeId"];
|
|
534
|
+
nodes[i].status = node["status"];
|
|
535
|
+
nodes[i].lastSeen = node["lastSeen"];
|
|
536
|
+
nodes[i].signalStrength = node["rssi"];
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
meshId = jsonObj["meshId"].as<TSTRING>();
|
|
540
|
+
messageType = jsonObj["message_type"] | 600;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
544
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
545
|
+
|
|
546
|
+
JsonArray nodesArray = jsonObj["nodes"].to<JsonArray>();
|
|
547
|
+
for (uint8_t i = 0; i < nodeCount; i++) {
|
|
548
|
+
JsonObject node = nodesArray.add<JsonObject>();
|
|
549
|
+
node["nodeId"] = nodes[i].nodeId;
|
|
550
|
+
node["status"] = nodes[i].status;
|
|
551
|
+
node["lastSeen"] = nodes[i].lastSeen;
|
|
552
|
+
node["rssi"] = nodes[i].signalStrength;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
jsonObj["nodeCount"] = nodeCount;
|
|
556
|
+
jsonObj["meshId"] = meshId;
|
|
557
|
+
jsonObj["message_type"] = messageType;
|
|
558
|
+
|
|
559
|
+
return jsonObj;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
563
|
+
size_t jsonObjectSize() const {
|
|
564
|
+
return JSON_OBJECT_SIZE(noJsonFields + 3) + JSON_ARRAY_SIZE(nodeCount) +
|
|
565
|
+
nodeCount * JSON_OBJECT_SIZE(4) + meshId.length();
|
|
566
|
+
}
|
|
567
|
+
#endif
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* @brief Mesh connection information
|
|
572
|
+
*/
|
|
573
|
+
struct MeshConnection {
|
|
574
|
+
uint32_t fromNode = 0; // Source node ID
|
|
575
|
+
uint32_t toNode = 0; // Destination node ID
|
|
576
|
+
float linkQuality = 0.0; // Link quality 0.0-1.0
|
|
577
|
+
uint16_t latencyMs = 0; // Latency in milliseconds
|
|
578
|
+
uint8_t hopCount = 1; // Number of hops
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* @brief Mesh topology package (Type 601 - MESH_TOPOLOGY)
|
|
583
|
+
*
|
|
584
|
+
* Provides mesh network topology with all connections.
|
|
585
|
+
* Type ID 601 for MESH_TOPOLOGY per mqtt-schema v0.7.2+.
|
|
586
|
+
*/
|
|
587
|
+
class MeshTopologyPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
588
|
+
public:
|
|
589
|
+
// Array of connections (max 100 connections)
|
|
590
|
+
MeshConnection connections[100];
|
|
591
|
+
uint8_t connectionCount = 0; // Actual number of connections
|
|
592
|
+
uint32_t rootNode = 0; // Root/gateway node ID
|
|
593
|
+
|
|
594
|
+
// MQTT Schema v0.7.2+ message_type
|
|
595
|
+
uint16_t messageType = 601; // MESH_TOPOLOGY
|
|
596
|
+
|
|
597
|
+
MeshTopologyPackage() : BroadcastPackage(601) {}
|
|
598
|
+
|
|
599
|
+
MeshTopologyPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
600
|
+
JsonArray connsArray = jsonObj["connections"];
|
|
601
|
+
connectionCount = connsArray.size();
|
|
602
|
+
if (connectionCount > 100) connectionCount = 100;
|
|
603
|
+
|
|
604
|
+
for (uint8_t i = 0; i < connectionCount; i++) {
|
|
605
|
+
JsonObject conn = connsArray[i];
|
|
606
|
+
connections[i].fromNode = conn["from"];
|
|
607
|
+
connections[i].toNode = conn["to"];
|
|
608
|
+
connections[i].linkQuality = conn["quality"];
|
|
609
|
+
connections[i].latencyMs = conn["latency"];
|
|
610
|
+
connections[i].hopCount = conn["hops"];
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
rootNode = jsonObj["rootNode"];
|
|
614
|
+
messageType = jsonObj["message_type"] | 601;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
618
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
619
|
+
|
|
620
|
+
JsonArray connsArray = jsonObj["connections"].to<JsonArray>();
|
|
621
|
+
for (uint8_t i = 0; i < connectionCount; i++) {
|
|
622
|
+
JsonObject conn = connsArray.add<JsonObject>();
|
|
623
|
+
conn["from"] = connections[i].fromNode;
|
|
624
|
+
conn["to"] = connections[i].toNode;
|
|
625
|
+
conn["quality"] = connections[i].linkQuality;
|
|
626
|
+
conn["latency"] = connections[i].latencyMs;
|
|
627
|
+
conn["hops"] = connections[i].hopCount;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
jsonObj["totalConnections"] = connectionCount;
|
|
631
|
+
jsonObj["rootNode"] = rootNode;
|
|
632
|
+
jsonObj["message_type"] = messageType;
|
|
633
|
+
|
|
634
|
+
return jsonObj;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
638
|
+
size_t jsonObjectSize() const {
|
|
639
|
+
return JSON_OBJECT_SIZE(noJsonFields + 3) +
|
|
640
|
+
JSON_ARRAY_SIZE(connectionCount) +
|
|
641
|
+
connectionCount * JSON_OBJECT_SIZE(5);
|
|
642
|
+
}
|
|
643
|
+
#endif
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* @brief Mesh alert information
|
|
648
|
+
*/
|
|
649
|
+
struct MeshAlert {
|
|
650
|
+
uint8_t alertType =
|
|
651
|
+
0; // 0=low_memory, 1=node_offline, 2=connection_lost, etc.
|
|
652
|
+
uint8_t severity = 0; // 0=info, 1=warning, 2=critical
|
|
653
|
+
TSTRING message = ""; // Human-readable message
|
|
654
|
+
uint32_t nodeId = 0; // Related node ID
|
|
655
|
+
float metricValue = 0.0; // Related metric value
|
|
656
|
+
float threshold = 0.0; // Threshold that triggered alert
|
|
657
|
+
uint32_t alertId = 0; // Unique alert ID
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* @brief Mesh alert package (Type 602 - MESH_ALERT)
|
|
662
|
+
*
|
|
663
|
+
* Provides mesh network alerts for critical events.
|
|
664
|
+
* Type ID 602 for MESH_ALERT per mqtt-schema v0.7.2+.
|
|
665
|
+
*/
|
|
666
|
+
class MeshAlertPackage : public painlessmesh::plugin::BroadcastPackage {
|
|
667
|
+
public:
|
|
668
|
+
// Array of alerts (max 20 alerts)
|
|
669
|
+
MeshAlert alerts[20];
|
|
670
|
+
uint8_t alertCount = 0; // Actual number of alerts
|
|
671
|
+
|
|
672
|
+
// MQTT Schema v0.7.2+ message_type
|
|
673
|
+
uint16_t messageType = 602; // MESH_ALERT
|
|
674
|
+
|
|
675
|
+
MeshAlertPackage() : BroadcastPackage(602) {}
|
|
676
|
+
|
|
677
|
+
MeshAlertPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
678
|
+
JsonArray alertsArray = jsonObj["alerts"];
|
|
679
|
+
alertCount = alertsArray.size();
|
|
680
|
+
if (alertCount > 20) alertCount = 20;
|
|
681
|
+
|
|
682
|
+
for (uint8_t i = 0; i < alertCount; i++) {
|
|
683
|
+
JsonObject alert = alertsArray[i];
|
|
684
|
+
alerts[i].alertType = alert["type"];
|
|
685
|
+
alerts[i].severity = alert["severity"];
|
|
686
|
+
alerts[i].message = alert["msg"].as<TSTRING>();
|
|
687
|
+
alerts[i].nodeId = alert["nodeId"];
|
|
688
|
+
alerts[i].metricValue = alert["value"];
|
|
689
|
+
alerts[i].threshold = alert["threshold"];
|
|
690
|
+
alerts[i].alertId = alert["alertId"];
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
messageType = jsonObj["message_type"] | 602;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
697
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
698
|
+
|
|
699
|
+
JsonArray alertsArray = jsonObj["alerts"].to<JsonArray>();
|
|
700
|
+
for (uint8_t i = 0; i < alertCount; i++) {
|
|
701
|
+
JsonObject alert = alertsArray.add<JsonObject>();
|
|
702
|
+
alert["type"] = alerts[i].alertType;
|
|
703
|
+
alert["severity"] = alerts[i].severity;
|
|
704
|
+
alert["msg"] = alerts[i].message;
|
|
705
|
+
alert["nodeId"] = alerts[i].nodeId;
|
|
706
|
+
alert["value"] = alerts[i].metricValue;
|
|
707
|
+
alert["threshold"] = alerts[i].threshold;
|
|
708
|
+
alert["alertId"] = alerts[i].alertId;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
jsonObj["alertCount"] = alertCount;
|
|
712
|
+
jsonObj["message_type"] = messageType;
|
|
713
|
+
|
|
714
|
+
return jsonObj;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
718
|
+
size_t jsonObjectSize() const {
|
|
719
|
+
size_t size = JSON_OBJECT_SIZE(noJsonFields + 2) +
|
|
720
|
+
JSON_ARRAY_SIZE(alertCount) +
|
|
721
|
+
alertCount * JSON_OBJECT_SIZE(7);
|
|
722
|
+
for (uint8_t i = 0; i < alertCount; i++) {
|
|
723
|
+
size += alerts[i].message.length();
|
|
724
|
+
}
|
|
725
|
+
return size;
|
|
726
|
+
}
|
|
727
|
+
#endif
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* @brief Mesh bridge package (Type 603 - MESH_BRIDGE)
|
|
732
|
+
*
|
|
733
|
+
* Encapsulates native mesh protocol messages for bridging.
|
|
734
|
+
* Type ID 603 for MESH_BRIDGE per mqtt-schema v0.7.2+.
|
|
735
|
+
*/
|
|
736
|
+
class MeshBridgePackage : public painlessmesh::plugin::BroadcastPackage {
|
|
737
|
+
public:
|
|
738
|
+
uint8_t meshProtocol = 0; // 0=painlessMesh, 1=esp-now, 2=ble-mesh, etc.
|
|
739
|
+
uint32_t fromNodeId = 0; // Source node ID
|
|
740
|
+
uint32_t toNodeId = 0; // Destination node ID (0=broadcast)
|
|
741
|
+
uint16_t meshType = 0; // Mesh protocol-specific message type
|
|
742
|
+
TSTRING rawPayload = ""; // Raw payload (hex/base64 encoded)
|
|
743
|
+
int8_t rssi = 0; // Signal strength
|
|
744
|
+
uint8_t hopCount = 0; // Number of hops
|
|
745
|
+
uint32_t meshTimestamp = 0; // Mesh protocol timestamp
|
|
746
|
+
uint32_t gatewayNodeId = 0; // Gateway's node ID
|
|
747
|
+
TSTRING meshNetworkId = ""; // Mesh network identifier
|
|
748
|
+
|
|
749
|
+
// MQTT Schema v0.7.2+ message_type
|
|
750
|
+
uint16_t messageType = 603; // MESH_BRIDGE
|
|
751
|
+
|
|
752
|
+
MeshBridgePackage() : BroadcastPackage(603) {}
|
|
753
|
+
|
|
754
|
+
MeshBridgePackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
|
|
755
|
+
meshProtocol = jsonObj["protocol"];
|
|
756
|
+
fromNodeId = jsonObj["fromNode"];
|
|
757
|
+
toNodeId = jsonObj["toNode"];
|
|
758
|
+
meshType = jsonObj["meshType"];
|
|
759
|
+
rawPayload = jsonObj["payload"].as<TSTRING>();
|
|
760
|
+
rssi = jsonObj["rssi"];
|
|
761
|
+
hopCount = jsonObj["hops"];
|
|
762
|
+
meshTimestamp = jsonObj["meshTs"];
|
|
763
|
+
gatewayNodeId = jsonObj["gateway"];
|
|
764
|
+
meshNetworkId = jsonObj["meshId"].as<TSTRING>();
|
|
765
|
+
messageType = jsonObj["message_type"] | 603;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
JsonObject addTo(JsonObject&& jsonObj) const {
|
|
769
|
+
jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
|
|
770
|
+
|
|
771
|
+
jsonObj["protocol"] = meshProtocol;
|
|
772
|
+
jsonObj["fromNode"] = fromNodeId;
|
|
773
|
+
jsonObj["toNode"] = toNodeId;
|
|
774
|
+
jsonObj["meshType"] = meshType;
|
|
775
|
+
jsonObj["payload"] = rawPayload;
|
|
776
|
+
jsonObj["rssi"] = rssi;
|
|
777
|
+
jsonObj["hops"] = hopCount;
|
|
778
|
+
jsonObj["meshTs"] = meshTimestamp;
|
|
779
|
+
jsonObj["gateway"] = gatewayNodeId;
|
|
780
|
+
jsonObj["meshId"] = meshNetworkId;
|
|
781
|
+
jsonObj["message_type"] = messageType;
|
|
782
|
+
|
|
783
|
+
return jsonObj;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
#if ARDUINOJSON_VERSION_MAJOR < 7
|
|
787
|
+
size_t jsonObjectSize() const {
|
|
788
|
+
return JSON_OBJECT_SIZE(noJsonFields + 11) + rawPayload.length() +
|
|
789
|
+
meshNetworkId.length();
|
|
790
|
+
}
|
|
791
|
+
#endif
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
} // namespace alteriom
|
|
795
|
+
|
|
796
|
+
#endif // ALTERIOM_SENSOR_PACKAGE_HPP
|