@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.
Files changed (129) hide show
  1. package/CHANGELOG.md +380 -143
  2. package/LICENSE +674 -674
  3. package/README.md +477 -434
  4. package/RELEASE_GUIDE.md +504 -418
  5. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +175 -175
  6. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +1062 -0
  7. package/docs/MESH_TOPOLOGY_GUIDE.md +992 -0
  8. package/docs/MESH_TOPOLOGY_PROGRESS.md +422 -0
  9. package/docs/MQTT_BRIDGE_COMMANDS.md +894 -0
  10. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +324 -0
  11. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +576 -0
  12. package/docs/MQTT_SCHEMA_COMPLIANCE.md +285 -0
  13. package/docs/MQTT_SCHEMA_PROPOSALS.md +446 -0
  14. package/docs/MQTT_SCHEMA_REVIEW.md +690 -0
  15. package/docs/OTA_COMMANDS_REFERENCE.md +554 -0
  16. package/docs/PHASE1_GUIDE.md +349 -0
  17. package/docs/PHASE2_GUIDE.md +543 -0
  18. package/docs/README.md +77 -70
  19. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +222 -0
  20. package/docs/alteriom/overview.md +507 -507
  21. package/docs/api/core-api.md +606 -606
  22. package/docs/architecture/mesh-architecture.md +378 -378
  23. package/docs/architecture/plugin-system.md +516 -516
  24. package/docs/getting-started/first-mesh.md +409 -409
  25. package/docs/getting-started/installation.md +274 -274
  26. package/docs/getting-started/quickstart.md +157 -157
  27. package/docs/improvements/FEATURE_PROPOSALS.md +337 -0
  28. package/docs/improvements/PHASE1_IMPLEMENTATION.md +325 -0
  29. package/docs/improvements/PHASE2_IMPLEMENTATION.md +567 -0
  30. package/docs/improvements/README.md +86 -68
  31. package/docs/improvements/ota-and-status-enhancements.md +911 -0
  32. package/docs/improvements/ota-status-architecture-diagrams.md +658 -0
  33. package/docs/improvements/ota-status-quick-reference.md +284 -0
  34. package/docs/platformio-publishing.md +255 -0
  35. package/docs/platformio-setup-summary.md +121 -0
  36. package/docs/troubleshooting/common-issues.md +520 -520
  37. package/docs/troubleshooting/faq.md +472 -472
  38. package/docs/tutorials/basic-examples.md +717 -717
  39. package/docs/wiki/API-Reference.md +245 -245
  40. package/docs/wiki/Complete-Documentation.md +122 -122
  41. package/examples/alteriom/README.md +139 -81
  42. package/examples/alteriom/alteriom.ino +186 -185
  43. package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
  44. package/examples/alteriom/platformio.ini +24 -24
  45. package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
  46. package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
  47. package/examples/alteriomImproved/platformio.ini +25 -0
  48. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
  49. package/examples/alteriomPhase1/phase1_features.ino +242 -0
  50. package/examples/alteriomPhase1/platformio.ini +25 -0
  51. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
  52. package/examples/alteriomPhase2/phase2_features.ino +186 -0
  53. package/examples/alteriomPhase2/platformio.ini +25 -0
  54. package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
  55. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
  56. package/examples/alteriomSensorNode/platformio.ini +25 -0
  57. package/examples/basic/basic.ino +66 -66
  58. package/examples/basic/platformio.ini +25 -25
  59. package/examples/bridge/bridge.ino +51 -51
  60. package/examples/bridge/mesh_event_publisher.hpp +253 -0
  61. package/examples/bridge/mesh_topology_reporter.hpp +303 -0
  62. package/examples/bridge/mqtt_command_bridge.hpp +459 -0
  63. package/examples/bridge/mqtt_status_bridge.hpp +519 -0
  64. package/examples/bridge/platformio.ini +25 -25
  65. package/examples/echoNode/echoNode.ino +33 -33
  66. package/examples/echoNode/platformio.ini +25 -25
  67. package/examples/logClient/logClient.ino +109 -109
  68. package/examples/logClient/platformio.ini +25 -25
  69. package/examples/logServer/logServer.ino +81 -81
  70. package/examples/logServer/platformio.ini +25 -25
  71. package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
  72. package/examples/meshCommandNode/meshCommandNode.ino +263 -0
  73. package/examples/meshCommandNode/platformio.ini +25 -0
  74. package/examples/mqttBridge/mqttBridge.ino +118 -118
  75. package/examples/mqttBridge/platformio.ini +26 -26
  76. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
  77. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
  78. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
  79. package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
  80. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
  81. package/examples/mqttCommandBridge/platformio.ini +26 -0
  82. package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
  83. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
  84. package/examples/mqttStatusBridge/platformio.ini +26 -0
  85. package/examples/mqttTopologyTest/README.md +467 -0
  86. package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
  87. package/examples/mqttTopologyTest/platformio.ini +26 -0
  88. package/examples/namedMesh/namedMesh.ino +97 -97
  89. package/examples/namedMesh/platformio.ini +25 -25
  90. package/examples/otaReceiver/otaReceiver.ino +79 -79
  91. package/examples/otaReceiver/platformio.ini +25 -25
  92. package/examples/otaSender/otaSender.ino +160 -151
  93. package/examples/otaSender/platformio.ini +25 -25
  94. package/examples/startHere/platformio.ini +25 -25
  95. package/examples/startHere/startHere.ino +159 -159
  96. package/examples/webServer/platformio.ini +27 -27
  97. package/examples/webServer/webServer.ino +89 -89
  98. package/keywords.txt +48 -48
  99. package/library.json +55 -34
  100. package/library.properties +10 -10
  101. package/package.json +86 -78
  102. package/src/AlteriomPainlessMesh.h +97 -97
  103. package/src/arduino/wifi.hpp +365 -365
  104. package/src/boost/asynctcp.hpp +279 -279
  105. package/src/painlessMesh.h +70 -70
  106. package/src/painlessMeshSTA.cpp +236 -236
  107. package/src/painlessMeshSTA.h +58 -58
  108. package/src/painlessTaskOptions.h +4 -4
  109. package/src/painlessmesh/base64.hpp +111 -111
  110. package/src/painlessmesh/buffer.hpp +229 -229
  111. package/src/painlessmesh/callback.hpp +91 -91
  112. package/src/painlessmesh/configuration.hpp +77 -77
  113. package/src/painlessmesh/connection.hpp +192 -192
  114. package/src/painlessmesh/layout.hpp +188 -188
  115. package/src/painlessmesh/logger.hpp +158 -158
  116. package/src/painlessmesh/memory.hpp +119 -119
  117. package/src/painlessmesh/mesh.hpp +761 -560
  118. package/src/painlessmesh/metrics.hpp +322 -322
  119. package/src/painlessmesh/ntp.hpp +263 -263
  120. package/src/painlessmesh/ota.hpp +582 -553
  121. package/src/painlessmesh/plugin.hpp +188 -188
  122. package/src/painlessmesh/protocol.hpp +813 -813
  123. package/src/painlessmesh/router.hpp +322 -322
  124. package/src/painlessmesh/tcp.hpp +71 -71
  125. package/src/painlessmesh/validation.hpp +238 -238
  126. package/src/plugin/performance.hpp +214 -214
  127. package/src/plugin/remote.hpp +64 -64
  128. package/src/scheduler.cpp +10 -10
  129. package/src/wifi.cpp +2 -2
@@ -1,128 +1,241 @@
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
- double temperature = 0.0; // Temperature in Celsius
17
- double humidity = 0.0; // Relative humidity percentage
18
- double pressure = 0.0; // Atmospheric pressure in hPa
19
- uint32_t sensorId = 0; // Unique sensor identifier
20
- uint32_t timestamp = 0; // Unix timestamp of measurement
21
- uint8_t batteryLevel = 0; // Battery level percentage
22
-
23
- SensorPackage()
24
- : BroadcastPackage(200) {} // Type ID 200 for Alteriom sensors
25
-
26
- SensorPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
27
- temperature = jsonObj["temp"];
28
- humidity = jsonObj["hum"];
29
- pressure = jsonObj["press"];
30
- sensorId = jsonObj["sid"];
31
- timestamp = jsonObj["ts"];
32
- batteryLevel = jsonObj["bat"];
33
- }
34
-
35
- JsonObject addTo(JsonObject&& jsonObj) const {
36
- jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
37
- jsonObj["temp"] = temperature;
38
- jsonObj["hum"] = humidity;
39
- jsonObj["press"] = pressure;
40
- jsonObj["sid"] = sensorId;
41
- jsonObj["ts"] = timestamp;
42
- jsonObj["bat"] = batteryLevel;
43
- return jsonObj;
44
- }
45
-
46
- #if ARDUINOJSON_VERSION_MAJOR < 7
47
- size_t jsonObjectSize() const { return JSON_OBJECT_SIZE(noJsonFields + 6); }
48
- #endif
49
- };
50
-
51
- /**
52
- * @brief Command package for controlling Alteriom devices
53
- *
54
- * Single-destination package for sending specific commands to individual nodes.
55
- */
56
- class CommandPackage : public painlessmesh::plugin::SinglePackage {
57
- public:
58
- uint8_t command = 0; // Command type
59
- uint32_t targetDevice = 0; // Target device ID
60
- TSTRING parameters = ""; // Command parameters as JSON string
61
- uint32_t commandId = 0; // Unique command identifier for tracking
62
-
63
- CommandPackage() : SinglePackage(201) {} // Type ID 201 for Alteriom commands
64
-
65
- CommandPackage(JsonObject jsonObj) : SinglePackage(jsonObj) {
66
- command = jsonObj["cmd"];
67
- targetDevice = jsonObj["target"];
68
- parameters = jsonObj["params"].as<TSTRING>();
69
- commandId = jsonObj["cid"];
70
- }
71
-
72
- JsonObject addTo(JsonObject&& jsonObj) const {
73
- jsonObj = SinglePackage::addTo(std::move(jsonObj));
74
- jsonObj["cmd"] = command;
75
- jsonObj["target"] = targetDevice;
76
- jsonObj["params"] = parameters;
77
- jsonObj["cid"] = commandId;
78
- return jsonObj;
79
- }
80
-
81
- #if ARDUINOJSON_VERSION_MAJOR < 7
82
- size_t jsonObjectSize() const {
83
- return JSON_OBJECT_SIZE(noJsonFields + 4) + parameters.length();
84
- }
85
- #endif
86
- };
87
-
88
- /**
89
- * @brief Status report package for device health monitoring
90
- */
91
- class StatusPackage : public painlessmesh::plugin::BroadcastPackage {
92
- public:
93
- uint8_t deviceStatus = 0; // Device status flags
94
- uint32_t uptime = 0; // Device uptime in seconds
95
- uint16_t freeMemory = 0; // Free memory in KB
96
- uint8_t wifiStrength = 0; // WiFi signal strength
97
- TSTRING firmwareVersion = ""; // Current firmware version
98
-
99
- StatusPackage() : BroadcastPackage(202) {} // Type ID 202 for Alteriom status
100
-
101
- StatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
102
- deviceStatus = jsonObj["status"];
103
- uptime = jsonObj["uptime"];
104
- freeMemory = jsonObj["mem"];
105
- wifiStrength = jsonObj["wifi"];
106
- firmwareVersion = jsonObj["fw"].as<TSTRING>();
107
- }
108
-
109
- JsonObject addTo(JsonObject&& jsonObj) const {
110
- jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
111
- jsonObj["status"] = deviceStatus;
112
- jsonObj["uptime"] = uptime;
113
- jsonObj["mem"] = freeMemory;
114
- jsonObj["wifi"] = wifiStrength;
115
- jsonObj["fw"] = firmwareVersion;
116
- return jsonObj;
117
- }
118
-
119
- #if ARDUINOJSON_VERSION_MAJOR < 7
120
- size_t jsonObjectSize() const {
121
- return JSON_OBJECT_SIZE(noJsonFields + 5) + firmwareVersion.length();
122
- }
123
- #endif
124
- };
125
-
126
- } // namespace alteriom
127
-
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() : SinglePackage(201) {} // Type ID 201 for Alteriom commands
70
+
71
+ CommandPackage(JsonObject jsonObj) : SinglePackage(jsonObj) {
72
+ command = jsonObj["cmd"];
73
+ targetDevice = jsonObj["target"];
74
+ parameters = jsonObj["params"].as<TSTRING>();
75
+ commandId = jsonObj["cid"];
76
+ }
77
+
78
+ JsonObject addTo(JsonObject&& jsonObj) const {
79
+ jsonObj = SinglePackage::addTo(std::move(jsonObj));
80
+ jsonObj["cmd"] = command;
81
+ jsonObj["target"] = targetDevice;
82
+ jsonObj["params"] = parameters;
83
+ jsonObj["cid"] = commandId;
84
+ return jsonObj;
85
+ }
86
+
87
+ #if ARDUINOJSON_VERSION_MAJOR < 7
88
+ size_t jsonObjectSize() const {
89
+ return JSON_OBJECT_SIZE(noJsonFields + 4) + parameters.length();
90
+ }
91
+ #endif
92
+ };
93
+
94
+ /**
95
+ * @brief Status report package for device health monitoring
96
+ */
97
+ class StatusPackage : public painlessmesh::plugin::BroadcastPackage {
98
+ public:
99
+ uint8_t deviceStatus = 0; // Device status flags
100
+ uint32_t uptime = 0; // Device uptime in seconds
101
+ uint16_t freeMemory = 0; // Free memory in KB
102
+ uint8_t wifiStrength = 0; // WiFi signal strength
103
+ TSTRING firmwareVersion = ""; // Current firmware version
104
+
105
+ // Command response fields (for MQTT bridge)
106
+ uint32_t responseToCommand = 0; // CommandId this is responding to
107
+ TSTRING responseMessage = ""; // Success/error message
108
+
109
+ StatusPackage() : BroadcastPackage(202) {} // Type ID 202 for Alteriom status
110
+
111
+ StatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
112
+ deviceStatus = jsonObj["status"];
113
+ uptime = jsonObj["uptime"];
114
+ freeMemory = jsonObj["mem"];
115
+ wifiStrength = jsonObj["wifi"];
116
+ firmwareVersion = jsonObj["fw"].as<TSTRING>();
117
+ responseToCommand = jsonObj["respTo"] | 0;
118
+ responseMessage = jsonObj["respMsg"].as<TSTRING>();
119
+ }
120
+
121
+ JsonObject addTo(JsonObject&& jsonObj) const {
122
+ jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
123
+ jsonObj["status"] = deviceStatus;
124
+ jsonObj["uptime"] = uptime;
125
+ jsonObj["mem"] = freeMemory;
126
+ jsonObj["wifi"] = wifiStrength;
127
+ jsonObj["fw"] = firmwareVersion;
128
+ if (responseToCommand > 0) {
129
+ jsonObj["respTo"] = responseToCommand;
130
+ jsonObj["respMsg"] = responseMessage;
131
+ }
132
+ return jsonObj;
133
+ }
134
+
135
+ #if ARDUINOJSON_VERSION_MAJOR < 7
136
+ size_t jsonObjectSize() const {
137
+ return JSON_OBJECT_SIZE(noJsonFields + 7) + firmwareVersion.length() +
138
+ responseMessage.length();
139
+ }
140
+ #endif
141
+ };
142
+
143
+ /**
144
+ * @brief Enhanced status package with comprehensive health metrics (Phase 1)
145
+ *
146
+ * This is an extended version of StatusPackage that includes additional
147
+ * mesh statistics, performance metrics, and alerting capabilities.
148
+ * Type ID 203 is used to distinguish from the basic StatusPackage (202).
149
+ */
150
+ class EnhancedStatusPackage : public painlessmesh::plugin::BroadcastPackage {
151
+ public:
152
+ // Device Health (from original StatusPackage)
153
+ uint8_t deviceStatus = 0; // Device status flags
154
+ uint32_t uptime = 0; // Device uptime in seconds
155
+ uint16_t freeMemory = 0; // Free memory in KB
156
+ uint8_t wifiStrength = 0; // WiFi signal strength
157
+ TSTRING firmwareVersion = ""; // Current firmware version
158
+ TSTRING firmwareMD5 = ""; // Firmware hash for OTA verification
159
+
160
+ // Mesh Statistics
161
+ uint16_t nodeCount = 0; // Number of known nodes in mesh
162
+ uint8_t connectionCount = 0; // Number of direct connections
163
+ uint32_t messagesReceived = 0; // Total messages received
164
+ uint32_t messagesSent = 0; // Total messages sent
165
+ uint32_t messagesDropped = 0; // Total messages dropped/failed
166
+
167
+ // Performance Metrics
168
+ uint16_t avgLatency = 0; // Average message latency in ms
169
+ uint8_t packetLossRate = 0; // Packet loss rate percentage (0-100)
170
+ uint16_t throughput = 0; // Network throughput in bytes/sec
171
+
172
+ // Warnings/Alerts
173
+ uint8_t alertFlags = 0; // Bit flags for various alert conditions
174
+ TSTRING lastError = ""; // Last error message for diagnostics
175
+
176
+ EnhancedStatusPackage()
177
+ : BroadcastPackage(203) {} // Type ID 203 for enhanced status
178
+
179
+ EnhancedStatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
180
+ deviceStatus = jsonObj["status"];
181
+ uptime = jsonObj["uptime"];
182
+ freeMemory = jsonObj["mem"];
183
+ wifiStrength = jsonObj["wifi"];
184
+ firmwareVersion = jsonObj["fw"].as<TSTRING>();
185
+ firmwareMD5 = jsonObj["fwMD5"].as<TSTRING>();
186
+
187
+ nodeCount = jsonObj["nodes"];
188
+ connectionCount = jsonObj["conns"];
189
+ messagesReceived = jsonObj["msgRx"];
190
+ messagesSent = jsonObj["msgTx"];
191
+ messagesDropped = jsonObj["msgDrop"];
192
+
193
+ avgLatency = jsonObj["latency"];
194
+ packetLossRate = jsonObj["loss"];
195
+ throughput = jsonObj["throughput"];
196
+
197
+ alertFlags = jsonObj["alerts"];
198
+ lastError = jsonObj["lastErr"].as<TSTRING>();
199
+ }
200
+
201
+ JsonObject addTo(JsonObject&& jsonObj) const {
202
+ jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
203
+
204
+ // Device Health
205
+ jsonObj["status"] = deviceStatus;
206
+ jsonObj["uptime"] = uptime;
207
+ jsonObj["mem"] = freeMemory;
208
+ jsonObj["wifi"] = wifiStrength;
209
+ jsonObj["fw"] = firmwareVersion;
210
+ jsonObj["fwMD5"] = firmwareMD5;
211
+
212
+ // Mesh Statistics
213
+ jsonObj["nodes"] = nodeCount;
214
+ jsonObj["conns"] = connectionCount;
215
+ jsonObj["msgRx"] = messagesReceived;
216
+ jsonObj["msgTx"] = messagesSent;
217
+ jsonObj["msgDrop"] = messagesDropped;
218
+
219
+ // Performance Metrics
220
+ jsonObj["latency"] = avgLatency;
221
+ jsonObj["loss"] = packetLossRate;
222
+ jsonObj["throughput"] = throughput;
223
+
224
+ // Alerts
225
+ jsonObj["alerts"] = alertFlags;
226
+ jsonObj["lastErr"] = lastError;
227
+
228
+ return jsonObj;
229
+ }
230
+
231
+ #if ARDUINOJSON_VERSION_MAJOR < 7
232
+ size_t jsonObjectSize() const {
233
+ return JSON_OBJECT_SIZE(noJsonFields + 18) + firmwareVersion.length() +
234
+ firmwareMD5.length() + lastError.length();
235
+ }
236
+ #endif
237
+ };
238
+
239
+ } // namespace alteriom
240
+
128
241
  #endif // ALTERIOM_SENSOR_PACKAGE_HPP
@@ -1,25 +1,25 @@
1
- [platformio]
2
- src_dir = .
3
-
4
- [env]
5
- lib_deps =
6
- bblanchon/ArduinoJson
7
- arkhipenko/TaskScheduler
8
-
9
- [env:esp8266]
10
- platform = espressif8266
11
- board = nodemcuv2
12
- framework = arduino
13
- lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
14
- lib_deps =
15
- ${env.lib_deps} ; Inherit common dependencies
16
- esp32async/ESPAsyncTCP ; Only for ESP8266
17
-
18
- [env:esp32]
19
- platform = espressif32
20
- board = esp32dev
21
- framework = arduino
22
- lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
23
- lib_deps =
24
- ${env.lib_deps} ; Inherit common dependencies
1
+ [platformio]
2
+ src_dir = .
3
+
4
+ [env]
5
+ lib_deps =
6
+ bblanchon/ArduinoJson
7
+ arkhipenko/TaskScheduler
8
+
9
+ [env:esp8266]
10
+ platform = espressif8266
11
+ board = nodemcuv2
12
+ framework = arduino
13
+ lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
14
+ lib_deps =
15
+ ${env.lib_deps} ; Inherit common dependencies
16
+ esp32async/ESPAsyncTCP ; Only for ESP8266
17
+
18
+ [env:esp32]
19
+ platform = espressif32
20
+ board = esp32dev
21
+ framework = arduino
22
+ lib_extra_dirs = ../../ ; Load the local copy of painlessmesh. For your own example add painlessmesh to the lib_deps
23
+ lib_deps =
24
+ ${env.lib_deps} ; Inherit common dependencies
25
25
  esp32async/AsyncTCP
@@ -0,0 +1,224 @@
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
+ double temperature = 0.0; // Temperature in Celsius
17
+ double humidity = 0.0; // Relative humidity percentage
18
+ double pressure = 0.0; // Atmospheric pressure in hPa
19
+ uint32_t sensorId = 0; // Unique sensor identifier
20
+ uint32_t timestamp = 0; // Unix timestamp of measurement
21
+ uint8_t batteryLevel = 0; // Battery level percentage
22
+
23
+ SensorPackage()
24
+ : BroadcastPackage(200) {} // Type ID 200 for Alteriom sensors
25
+
26
+ SensorPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
27
+ temperature = jsonObj["temp"];
28
+ humidity = jsonObj["hum"];
29
+ pressure = jsonObj["press"];
30
+ sensorId = jsonObj["sid"];
31
+ timestamp = jsonObj["ts"];
32
+ batteryLevel = jsonObj["bat"];
33
+ }
34
+
35
+ JsonObject addTo(JsonObject&& jsonObj) const {
36
+ jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
37
+ jsonObj["temp"] = temperature;
38
+ jsonObj["hum"] = humidity;
39
+ jsonObj["press"] = pressure;
40
+ jsonObj["sid"] = sensorId;
41
+ jsonObj["ts"] = timestamp;
42
+ jsonObj["bat"] = batteryLevel;
43
+ return jsonObj;
44
+ }
45
+
46
+ #if ARDUINOJSON_VERSION_MAJOR < 7
47
+ size_t jsonObjectSize() const { return JSON_OBJECT_SIZE(noJsonFields + 6); }
48
+ #endif
49
+ };
50
+
51
+ /**
52
+ * @brief Command package for controlling Alteriom devices
53
+ *
54
+ * Single-destination package for sending specific commands to individual nodes.
55
+ */
56
+ class CommandPackage : public painlessmesh::plugin::SinglePackage {
57
+ public:
58
+ uint8_t command = 0; // Command type
59
+ uint32_t targetDevice = 0; // Target device ID
60
+ TSTRING parameters = ""; // Command parameters as JSON string
61
+ uint32_t commandId = 0; // Unique command identifier for tracking
62
+
63
+ CommandPackage() : SinglePackage(201) {} // Type ID 201 for Alteriom commands
64
+
65
+ CommandPackage(JsonObject jsonObj) : SinglePackage(jsonObj) {
66
+ command = jsonObj["cmd"];
67
+ targetDevice = jsonObj["target"];
68
+ parameters = jsonObj["params"].as<TSTRING>();
69
+ commandId = jsonObj["cid"];
70
+ }
71
+
72
+ JsonObject addTo(JsonObject&& jsonObj) const {
73
+ jsonObj = SinglePackage::addTo(std::move(jsonObj));
74
+ jsonObj["cmd"] = command;
75
+ jsonObj["target"] = targetDevice;
76
+ jsonObj["params"] = parameters;
77
+ jsonObj["cid"] = commandId;
78
+ return jsonObj;
79
+ }
80
+
81
+ #if ARDUINOJSON_VERSION_MAJOR < 7
82
+ size_t jsonObjectSize() const {
83
+ return JSON_OBJECT_SIZE(noJsonFields + 4) + parameters.length();
84
+ }
85
+ #endif
86
+ };
87
+
88
+ /**
89
+ * @brief Status report package for device health monitoring
90
+ */
91
+ class StatusPackage : public painlessmesh::plugin::BroadcastPackage {
92
+ public:
93
+ uint8_t deviceStatus = 0; // Device status flags
94
+ uint32_t uptime = 0; // Device uptime in seconds
95
+ uint16_t freeMemory = 0; // Free memory in KB
96
+ uint8_t wifiStrength = 0; // WiFi signal strength
97
+ TSTRING firmwareVersion = ""; // Current firmware version
98
+
99
+ StatusPackage() : BroadcastPackage(202) {} // Type ID 202 for Alteriom status
100
+
101
+ StatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
102
+ deviceStatus = jsonObj["status"];
103
+ uptime = jsonObj["uptime"];
104
+ freeMemory = jsonObj["mem"];
105
+ wifiStrength = jsonObj["wifi"];
106
+ firmwareVersion = jsonObj["fw"].as<TSTRING>();
107
+ }
108
+
109
+ JsonObject addTo(JsonObject&& jsonObj) const {
110
+ jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
111
+ jsonObj["status"] = deviceStatus;
112
+ jsonObj["uptime"] = uptime;
113
+ jsonObj["mem"] = freeMemory;
114
+ jsonObj["wifi"] = wifiStrength;
115
+ jsonObj["fw"] = firmwareVersion;
116
+ return jsonObj;
117
+ }
118
+
119
+ #if ARDUINOJSON_VERSION_MAJOR < 7
120
+ size_t jsonObjectSize() const {
121
+ return JSON_OBJECT_SIZE(noJsonFields + 5) + firmwareVersion.length();
122
+ }
123
+ #endif
124
+ };
125
+
126
+ /**
127
+ * @brief Enhanced status package with comprehensive health metrics (Phase 1)
128
+ *
129
+ * This is an extended version of StatusPackage that includes additional
130
+ * mesh statistics, performance metrics, and alerting capabilities.
131
+ * Type ID 203 is used to distinguish from the basic StatusPackage (202).
132
+ */
133
+ class EnhancedStatusPackage : public painlessmesh::plugin::BroadcastPackage {
134
+ public:
135
+ // Device Health (from original StatusPackage)
136
+ uint8_t deviceStatus = 0; // Device status flags
137
+ uint32_t uptime = 0; // Device uptime in seconds
138
+ uint16_t freeMemory = 0; // Free memory in KB
139
+ uint8_t wifiStrength = 0; // WiFi signal strength
140
+ TSTRING firmwareVersion = ""; // Current firmware version
141
+ TSTRING firmwareMD5 = ""; // Firmware hash for OTA verification
142
+
143
+ // Mesh Statistics
144
+ uint16_t nodeCount = 0; // Number of known nodes in mesh
145
+ uint8_t connectionCount = 0; // Number of direct connections
146
+ uint32_t messagesReceived = 0; // Total messages received
147
+ uint32_t messagesSent = 0; // Total messages sent
148
+ uint32_t messagesDropped = 0; // Total messages dropped/failed
149
+
150
+ // Performance Metrics
151
+ uint16_t avgLatency = 0; // Average message latency in ms
152
+ uint8_t packetLossRate = 0; // Packet loss rate percentage (0-100)
153
+ uint16_t throughput = 0; // Network throughput in bytes/sec
154
+
155
+ // Warnings/Alerts
156
+ uint8_t alertFlags = 0; // Bit flags for various alert conditions
157
+ TSTRING lastError = ""; // Last error message for diagnostics
158
+
159
+ EnhancedStatusPackage()
160
+ : BroadcastPackage(203) {} // Type ID 203 for enhanced status
161
+
162
+ EnhancedStatusPackage(JsonObject jsonObj) : BroadcastPackage(jsonObj) {
163
+ deviceStatus = jsonObj["status"];
164
+ uptime = jsonObj["uptime"];
165
+ freeMemory = jsonObj["mem"];
166
+ wifiStrength = jsonObj["wifi"];
167
+ firmwareVersion = jsonObj["fw"].as<TSTRING>();
168
+ firmwareMD5 = jsonObj["fwMD5"].as<TSTRING>();
169
+
170
+ nodeCount = jsonObj["nodes"];
171
+ connectionCount = jsonObj["conns"];
172
+ messagesReceived = jsonObj["msgRx"];
173
+ messagesSent = jsonObj["msgTx"];
174
+ messagesDropped = jsonObj["msgDrop"];
175
+
176
+ avgLatency = jsonObj["latency"];
177
+ packetLossRate = jsonObj["loss"];
178
+ throughput = jsonObj["throughput"];
179
+
180
+ alertFlags = jsonObj["alerts"];
181
+ lastError = jsonObj["lastErr"].as<TSTRING>();
182
+ }
183
+
184
+ JsonObject addTo(JsonObject&& jsonObj) const {
185
+ jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
186
+
187
+ // Device Health
188
+ jsonObj["status"] = deviceStatus;
189
+ jsonObj["uptime"] = uptime;
190
+ jsonObj["mem"] = freeMemory;
191
+ jsonObj["wifi"] = wifiStrength;
192
+ jsonObj["fw"] = firmwareVersion;
193
+ jsonObj["fwMD5"] = firmwareMD5;
194
+
195
+ // Mesh Statistics
196
+ jsonObj["nodes"] = nodeCount;
197
+ jsonObj["conns"] = connectionCount;
198
+ jsonObj["msgRx"] = messagesReceived;
199
+ jsonObj["msgTx"] = messagesSent;
200
+ jsonObj["msgDrop"] = messagesDropped;
201
+
202
+ // Performance Metrics
203
+ jsonObj["latency"] = avgLatency;
204
+ jsonObj["loss"] = packetLossRate;
205
+ jsonObj["throughput"] = throughput;
206
+
207
+ // Alerts
208
+ jsonObj["alerts"] = alertFlags;
209
+ jsonObj["lastErr"] = lastError;
210
+
211
+ return jsonObj;
212
+ }
213
+
214
+ #if ARDUINOJSON_VERSION_MAJOR < 7
215
+ size_t jsonObjectSize() const {
216
+ return JSON_OBJECT_SIZE(noJsonFields + 18) + firmwareVersion.length() +
217
+ firmwareMD5.length() + lastError.length();
218
+ }
219
+ #endif
220
+ };
221
+
222
+ } // namespace alteriom
223
+
224
+ #endif // ALTERIOM_SENSOR_PACKAGE_HPP