@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.
Files changed (208) hide show
  1. package/BRIDGE_TO_INTERNET.md +229 -0
  2. package/CHANGELOG.md +89 -1
  3. package/CONTRIBUTING.md +79 -0
  4. package/README.md +70 -143
  5. package/docs/README.md +1 -0
  6. package/docs/api/shared-gateway.md +1207 -0
  7. package/docs/troubleshooting/common-issues.md +28 -0
  8. package/docs/troubleshooting/faq.md +113 -12
  9. package/examples/basic/test/simulator/CMakeLists.txt +40 -0
  10. package/examples/basic/test/simulator/README.md +149 -0
  11. package/examples/basic/test/simulator/firmware/basic_firmware.hpp +117 -0
  12. package/examples/basic/test/simulator/scenarios/basic_mesh_test.yaml +81 -0
  13. package/examples/bridge/bridge.ino +17 -4
  14. package/examples/bridge_failover/README.md +81 -0
  15. package/examples/bridge_failover/bridge_failover.ino +51 -6
  16. package/examples/sharedGateway/README.md +235 -0
  17. package/examples/{meshCommandNode → sharedGateway}/platformio.ini +3 -2
  18. package/examples/sharedGateway/sharedGateway.ino +303 -0
  19. package/library.json +3 -22
  20. package/library.properties +1 -1
  21. package/package.json +3 -3
  22. package/src/arduino/wifi.hpp +380 -13
  23. package/src/painlessmesh/gateway.hpp +2120 -0
  24. package/src/painlessmesh/mesh.hpp +1034 -6
  25. package/src/painlessmesh/message_tracker.hpp +311 -0
  26. package/src/painlessmesh/protocol.hpp +6 -0
  27. package/DOCUMENTATION_INDEX.md +0 -146
  28. package/docs/API_DESIGN_GUIDELINES.md +0 -414
  29. package/docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md +0 -331
  30. package/docs/BOOLEAN_NAMING_CONVENTION.md +0 -235
  31. package/docs/BRIDGE_FAILOVER.md +0 -512
  32. package/docs/BRIDGE_HEALTH_MONITORING.md +0 -293
  33. package/docs/CHANNEL_SYNCHRONIZATION.md +0 -209
  34. package/docs/CREATE_MISSING_RELEASES.md +0 -321
  35. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +0 -176
  36. package/docs/FAQ_VERSION_NUMBERS.md +0 -152
  37. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +0 -1062
  38. package/docs/MESH_TOPOLOGY_GUIDE.md +0 -992
  39. package/docs/MESH_TOPOLOGY_PROGRESS.md +0 -422
  40. package/docs/MQTT_BRIDGE_COMMANDS.md +0 -894
  41. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +0 -324
  42. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +0 -576
  43. package/docs/MQTT_SCHEMA_COMPLIANCE.md +0 -340
  44. package/docs/MQTT_SCHEMA_PROPOSALS.md +0 -446
  45. package/docs/MQTT_SCHEMA_REVIEW.md +0 -690
  46. package/docs/OTA_COMMANDS_REFERENCE.md +0 -554
  47. package/docs/PHASE1_GUIDE.md +0 -349
  48. package/docs/PHASE2_GUIDE.md +0 -543
  49. package/docs/QUICK_REFERENCE_VERSIONING.md +0 -127
  50. package/docs/RELEASE_AGENT_SUMMARY.md +0 -386
  51. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +0 -222
  52. package/docs/VERSION_MANAGEMENT.md +0 -213
  53. package/docs/archive/DOCUSAURUS_DEPLOYMENT.md +0 -166
  54. package/docs/archive/FEATURE_PROPOSALS.md +0 -337
  55. package/docs/archive/LIBRARY_JSON_FIX.md +0 -98
  56. package/docs/archive/LIBRARY_STRUCTURE_FIX.md +0 -215
  57. package/docs/archive/PHASE1_IMPLEMENTATION.md +0 -325
  58. package/docs/archive/PHASE2_IMPLEMENTATION.md +0 -567
  59. package/docs/archive/RELEASE_SUMMARY.md +0 -173
  60. package/docs/archive/SCONS_BUILD_FIX.md +0 -313
  61. package/docs/archive/TRIGGER_RELEASE.md +0 -280
  62. package/docs/archive/VECTOR_INCLUDE_FIX.md +0 -129
  63. package/docs/archive/ota-and-status-enhancements.md +0 -911
  64. package/docs/archive/ota-status-architecture-diagrams.md +0 -658
  65. package/docs/archive/ota-status-quick-reference.md +0 -284
  66. package/docs/design/.gitkeep +0 -1
  67. package/docs/design/STATION_CREDENTIALS_DESIGN.md +0 -182
  68. package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +0 -71
  69. package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +0 -1011
  70. package/docs/development/DOCKER_TESTING.md +0 -196
  71. package/docs/development/PLATFORMIO_USAGE.md +0 -180
  72. package/docs/development/TESTING_SUMMARY.md +0 -126
  73. package/docs/development/contributing.md +0 -301
  74. package/docs/development/documentation.md +0 -583
  75. package/docs/features/DIAGNOSTICS_API.md +0 -534
  76. package/docs/implementation/BRIDGE_ARCHITECTURE_IMPLEMENTATION.md +0 -340
  77. package/docs/implementation/BRIDGE_HEALTH_MONITORING_IMPLEMENTATION.md +0 -213
  78. package/docs/implementation/BRIDGE_STATUS_FEATURE.md +0 -635
  79. package/docs/implementation/DIAGNOSTICS_API_IMPLEMENTATION.md +0 -232
  80. package/docs/implementation/IMPLEMENTATION_COMPLETE.md +0 -228
  81. package/docs/implementation/IMPLEMENTATION_NTP_TIME_SYNC.md +0 -325
  82. package/docs/implementation/IMPLEMENTATION_SUMMARY.md +0 -316
  83. package/docs/implementation/MESSAGE_QUEUE_IMPLEMENTATION.md +0 -405
  84. package/docs/implementation/MULTI_BRIDGE_IMPLEMENTATION.md +0 -520
  85. package/docs/implementation/NTP_TIME_SYNC_FEATURE.md +0 -392
  86. package/docs/improvements/FUTURE_PROPOSALS.md +0 -1016
  87. package/docs/improvements/IMPLEMENTATION_HISTORY.md +0 -1091
  88. package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +0 -709
  89. package/docs/improvements/README.md +0 -212
  90. package/docs/internal/CUSTOM_AGENT_ANALYSIS.md +0 -391
  91. package/docs/internal/ISSUE_65_VERIFICATION.md +0 -947
  92. package/docs/internal/ISSUE_66_CLOSURE.md +0 -249
  93. package/docs/internal/ISSUE_66_STATUS.md +0 -316
  94. package/docs/internal/PR_SUMMARY.md +0 -315
  95. package/docs/internal/REVIEW_SUMMARY.md +0 -332
  96. package/docs/multi-bridge-setup.md +0 -1025
  97. package/docs/platformio-publishing.md +0 -255
  98. package/docs/platformio-setup-summary.md +0 -121
  99. package/docs/releases/ANNOUNCEMENT_v1.8.6.md +0 -63
  100. package/docs/releases/ANNOUNCEMENT_v1.8.7.md +0 -113
  101. package/docs/releases/BRIDGE_STATUS_SELF_REGISTRATION_FIX.md +0 -221
  102. package/docs/releases/FEATURE_HISTORY.md +0 -543
  103. package/docs/releases/GITHUB_RELEASE_v1.8.6.md +0 -71
  104. package/docs/releases/GITHUB_RELEASE_v1.8.7.md +0 -90
  105. package/docs/releases/PATCH_v1.7.2.md +0 -262
  106. package/docs/releases/PATCH_v1.7.3.md +0 -262
  107. package/docs/releases/PATCH_v1.7.4.md +0 -219
  108. package/docs/releases/PHASE1_SUMMARY.md +0 -246
  109. package/docs/releases/PHASE2_SUMMARY.md +0 -499
  110. package/docs/releases/PUBLISH_v1.8.0_INSTRUCTIONS.md +0 -163
  111. package/docs/releases/QUICK_START_RELEASES.md +0 -113
  112. package/docs/releases/RELEASE_CHECKLIST_1.8.10.md +0 -331
  113. package/docs/releases/RELEASE_CHECKLIST_1.8.9.md +0 -207
  114. package/docs/releases/RELEASE_CHECKLIST_v1.7.4.md +0 -253
  115. package/docs/releases/RELEASE_CHECKLIST_v1.7.5.md +0 -315
  116. package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +0 -389
  117. package/docs/releases/RELEASE_CHECKLIST_v1.8.0.md +0 -331
  118. package/docs/releases/RELEASE_CHECKLIST_v1.8.2.md +0 -309
  119. package/docs/releases/RELEASE_NOTES_1.7.0.md +0 -539
  120. package/docs/releases/RELEASE_NOTES_1.8.10.md +0 -239
  121. package/docs/releases/RELEASE_NOTES_1.8.9.md +0 -213
  122. package/docs/releases/RELEASE_NOTES_v1.8.0.md +0 -685
  123. package/docs/releases/RELEASE_NOTES_v1.8.1.md +0 -221
  124. package/docs/releases/RELEASE_NOTES_v1.8.2.md +0 -421
  125. package/docs/releases/RELEASE_NOTES_v1.8.3.md +0 -292
  126. package/docs/releases/RELEASE_NOTES_v1.8.4.md +0 -277
  127. package/docs/releases/RELEASE_NOTES_v1.8.6.md +0 -205
  128. package/docs/releases/RELEASE_NOTES_v1.8.7.md +0 -184
  129. package/docs/releases/RELEASE_PLAN_v1.7.6.md +0 -816
  130. package/docs/releases/RELEASE_SUMMARY_1.8.10.md +0 -193
  131. package/docs/releases/RELEASE_SUMMARY_v1.7.4.md +0 -276
  132. package/docs/releases/RELEASE_SUMMARY_v1.7.5.md +0 -322
  133. package/docs/releases/RELEASE_SUMMARY_v1.7.6.md +0 -436
  134. package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +0 -391
  135. package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +0 -523
  136. package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +0 -542
  137. package/docs/troubleshooting/ARDUINO_IDE_VERSION_FIX_SUMMARY.md +0 -229
  138. package/docs/troubleshooting/ARDUINO_LIBRARY_NAME_FIX.md +0 -197
  139. package/docs/troubleshooting/CRASH_QUICK_REF.md +0 -93
  140. package/docs/troubleshooting/ESP32_C6_COMPATIBILITY.md +0 -157
  141. package/docs/troubleshooting/FREERTOS_ASSERTION_FAILURE.md +0 -288
  142. package/docs/troubleshooting/FREERTOS_FIX_IMPLEMENTATION.md +0 -267
  143. package/docs/troubleshooting/NPM_PUBLISHING_ISSUE_SUMMARY.md +0 -110
  144. package/docs/troubleshooting/PAINLESSMESH_V1.7.4_COMPILATION_ISSUES.md +0 -547
  145. package/docs/troubleshooting/QUICK_FIX_FREERTOS.md +0 -164
  146. package/docs/troubleshooting/SENSOR_NODE_CONNECTION_CRASH.md +0 -264
  147. package/docs/troubleshooting/station-reconnection-issues.md +0 -172
  148. package/docs/v1.7.7_MQTT_IMPROVEMENTS.md +0 -794
  149. package/docs/wiki/API-Reference.md +0 -246
  150. package/docs/wiki/Complete-Documentation.md +0 -123
  151. package/examples/alteriomImproved/alteriom_sensor_package.hpp +0 -224
  152. package/examples/alteriomImproved/improved_sensor_node.ino +0 -248
  153. package/examples/alteriomImproved/platformio.ini +0 -32
  154. package/examples/alteriomMetricsHealth/alteriom_sensor_package.hpp +0 -796
  155. package/examples/alteriomMetricsHealth/metrics_health_node.ino +0 -429
  156. package/examples/alteriomMetricsHealth/platformio.ini +0 -26
  157. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +0 -224
  158. package/examples/alteriomPhase1/phase1_features.ino +0 -242
  159. package/examples/alteriomPhase1/platformio.ini +0 -26
  160. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +0 -224
  161. package/examples/alteriomPhase2/phase2_features.ino +0 -186
  162. package/examples/alteriomPhase2/platformio.ini +0 -26
  163. package/examples/alteriomSensorNode/alteriom_sensor_node.ino +0 -186
  164. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +0 -1227
  165. package/examples/alteriomSensorNode/platformio.ini +0 -26
  166. package/examples/bridge/alteriom_sensor_package.hpp +0 -1170
  167. package/examples/bridge/bridge_health_monitoring_example.ino +0 -188
  168. package/examples/bridge/enhanced_mqtt_bridge.hpp +0 -610
  169. package/examples/bridge/enhanced_mqtt_bridge_example.ino +0 -226
  170. package/examples/bridge/mesh_event_publisher.hpp +0 -253
  171. package/examples/bridge/mesh_topology_reporter.hpp +0 -303
  172. package/examples/bridge/mqtt_command_bridge.hpp +0 -459
  173. package/examples/bridge/mqtt_status_bridge.hpp +0 -519
  174. package/examples/bridgeAwareSensorNode/alteriom_sensor_package.hpp +0 -1227
  175. package/examples/bridgeAwareSensorNode/bridgeAwareSensorNode.ino +0 -342
  176. package/examples/bridgeAwareSensorNode/platformio.ini +0 -26
  177. package/examples/diagnosticsExample/diagnosticsExample.ino +0 -171
  178. package/examples/diagnosticsExample/platformio.ini +0 -26
  179. package/examples/echoNode/echoNode.ino +0 -33
  180. package/examples/echoNode/platformio.ini +0 -26
  181. package/examples/meshCommandNode/alteriom_sensor_package.hpp +0 -235
  182. package/examples/meshCommandNode/meshCommandNode.ino +0 -265
  183. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +0 -235
  184. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +0 -253
  185. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +0 -303
  186. package/examples/mqttCommandBridge/mqttCommandBridge.ino +0 -254
  187. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +0 -462
  188. package/examples/mqttCommandBridge/platformio.ini +0 -27
  189. package/examples/mqttStatusBridge/mqttStatusBridge.ino +0 -218
  190. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +0 -522
  191. package/examples/mqttStatusBridge/platformio.ini +0 -27
  192. package/examples/mqttTopologyTest/README.md +0 -467
  193. package/examples/mqttTopologyTest/mqttTopologyTest.ino +0 -754
  194. package/examples/mqttTopologyTest/platformio.ini +0 -27
  195. package/examples/multi_bridge/README.md +0 -346
  196. package/examples/multi_bridge/primary_bridge.ino +0 -96
  197. package/examples/multi_bridge/regular_node.ino +0 -141
  198. package/examples/multi_bridge/secondary_bridge.ino +0 -111
  199. package/examples/ntpTimeSyncBridge/alteriom_sensor_package.hpp +0 -1383
  200. package/examples/ntpTimeSyncBridge/ntpTimeSyncBridge.ino +0 -86
  201. package/examples/ntpTimeSyncNode/alteriom_sensor_package.hpp +0 -1383
  202. package/examples/ntpTimeSyncNode/ntpTimeSyncNode.ino +0 -109
  203. package/examples/queued_alarms/README.md +0 -390
  204. package/examples/queued_alarms/queued_alarms.ino +0 -265
  205. package/examples/routing_demo/README.md +0 -172
  206. package/examples/routing_demo/routing_demo.ino +0 -102
  207. package/examples/rtcIntegration/README.md +0 -294
  208. package/examples/rtcIntegration/rtcIntegration.ino +0 -210
@@ -1,294 +0,0 @@
1
- # RTC Integration Example
2
-
3
- This example demonstrates how to integrate Real-Time Clock (RTC) modules with painlessMesh for accurate offline timekeeping.
4
-
5
- ## Problem Statement
6
-
7
- When Internet or bridge connectivity is unavailable, mesh nodes lose access to accurate time synchronization. This is problematic for applications that require valid timestamps, such as:
8
-
9
- - Fish farm alarm systems (regulatory compliance)
10
- - Environmental monitoring with offline data logging
11
- - Industrial IoT with intermittent connectivity
12
- - Remote sensor networks
13
-
14
- ## Solution
15
-
16
- painlessMesh RTC integration provides:
17
-
18
- ✅ **Accurate timestamps during offline periods**
19
- ✅ **Automatic NTP sync when Internet available**
20
- ✅ **Graceful fallback to mesh time**
21
- ✅ **Support for common RTC modules**
22
-
23
- ## Supported RTC Modules
24
-
25
- - **DS3231** - High accuracy I2C RTC with temperature compensation
26
- - **DS1307** - Basic I2C RTC
27
- - **PCF8523** - Low power I2C RTC
28
- - **PCF8563** - Ultra-low power I2C RTC
29
- - **ESP32 Internal RTC** - Built-in ESP32 RTC (requires external battery backup)
30
-
31
- ## Hardware Requirements
32
-
33
- ### For DS3231 (used in this example)
34
- - ESP32 or ESP8266 board
35
- - DS3231 RTC module
36
- - Connections:
37
- - SDA → GPIO 21 (ESP32) or GPIO 4 (ESP8266)
38
- - SCL → GPIO 22 (ESP32) or GPIO 5 (ESP8266)
39
- - VCC → 3.3V
40
- - GND → GND
41
-
42
- ### Library Requirements
43
- ```
44
- painlessMesh
45
- RTClib (Adafruit)
46
- ```
47
-
48
- Install via Arduino Library Manager:
49
- - Tools → Manage Libraries
50
- - Search for "RTClib" by Adafruit
51
- - Click Install
52
-
53
- ## How It Works
54
-
55
- ### 1. RTC Interface Implementation
56
-
57
- You implement the `RTCInterface` for your specific RTC hardware:
58
-
59
- ```cpp
60
- class DS3231Interface : public painlessmesh::rtc::RTCInterface {
61
- // Implement begin(), isAvailable(), getUnixTime(), setUnixTime(), getType()
62
- };
63
- ```
64
-
65
- ### 2. Enable RTC
66
-
67
- ```cpp
68
- DS3231Interface rtcInterface(&rtc);
69
- mesh.enableRTC(&rtcInterface);
70
- ```
71
-
72
- ### 3. Automatic Time Management
73
-
74
- ```cpp
75
- mesh.onBridgeStatusChanged([](uint32_t bridgeNodeId, bool hasInternet) {
76
- if (hasInternet) {
77
- // Sync RTC from NTP when Internet available
78
- uint32_t ntpTime = getNTPTime();
79
- mesh.syncRTCFromNTP(ntpTime);
80
- }
81
- // Offline: RTC maintains accurate time
82
- });
83
- ```
84
-
85
- ### 4. Get Accurate Time
86
-
87
- ```cpp
88
- // Prefers RTC, falls back to mesh time
89
- uint32_t timestamp = mesh.getAccurateTime();
90
- ```
91
-
92
- ## API Reference
93
-
94
- ### Mesh Methods
95
-
96
- #### `bool enableRTC(rtc::RTCInterface* rtcInterface)`
97
- Enable RTC integration with a user-provided interface.
98
-
99
- **Returns:** `true` if RTC initialized successfully, `false` otherwise
100
-
101
- #### `void disableRTC()`
102
- Disable RTC integration.
103
-
104
- #### `bool syncRTCFromNTP(uint32_t ntpTimestamp)`
105
- Sync RTC from NTP/Internet time source.
106
-
107
- **Parameters:**
108
- - `ntpTimestamp` - Unix timestamp from NTP
109
-
110
- **Returns:** `true` if sync successful, `false` otherwise
111
-
112
- #### `uint32_t getAccurateTime()`
113
- Get accurate time with RTC fallback.
114
-
115
- **Returns:** Unix timestamp (seconds) from RTC, or mesh time (microseconds) if RTC unavailable
116
-
117
- #### `bool hasRTC()`
118
- Check if RTC is enabled and available.
119
-
120
- **Returns:** `true` if RTC can be used, `false` otherwise
121
-
122
- #### `rtc::RTCType getRTCType()`
123
- Get RTC module type.
124
-
125
- **Returns:** `RTCType` enum value
126
-
127
- #### `uint32_t getTimeSinceRTCSync()`
128
- Get time since last RTC sync.
129
-
130
- **Returns:** Milliseconds since last sync, or 0 if never synced
131
-
132
- #### `void onRTCSyncComplete(rtcSyncCompleteCallback_t callback)`
133
- Set callback for RTC sync completion.
134
-
135
- ### RTC Types
136
-
137
- ```cpp
138
- enum RTCType {
139
- RTC_NONE = 0,
140
- RTC_DS3231 = 1,
141
- RTC_DS1307 = 2,
142
- RTC_PCF8523 = 3,
143
- RTC_PCF8563 = 4,
144
- RTC_ESP32_INTERNAL = 5
145
- };
146
- ```
147
-
148
- ## Usage Example
149
-
150
- ```cpp
151
- #include "painlessMesh.h"
152
- #include <RTClib.h>
153
-
154
- painlessMesh mesh;
155
- RTC_DS3231 rtc;
156
- DS3231Interface rtcInterface(&rtc);
157
-
158
- void setup() {
159
- mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
160
- mesh.onBridgeStatusChanged(&bridgeStatusCallback);
161
- mesh.onRTCSyncComplete(&rtcSyncCompleteCallback);
162
-
163
- if (mesh.enableRTC(&rtcInterface)) {
164
- Serial.println("RTC enabled!");
165
- }
166
- }
167
-
168
- void bridgeStatusCallback(uint32_t bridgeNodeId, bool hasInternet) {
169
- if (hasInternet && mesh.hasRTC()) {
170
- uint32_t ntpTime = getNTPTime(); // Your implementation
171
- mesh.syncRTCFromNTP(ntpTime);
172
- }
173
- }
174
-
175
- void rtcSyncCompleteCallback(uint32_t timestamp) {
176
- Serial.printf("RTC synced to: %u\n", timestamp);
177
- }
178
- ```
179
-
180
- ## Testing
181
-
182
- ### Verify RTC Time Persistence
183
- 1. Upload sketch to node
184
- 2. Disconnect Internet/bridge
185
- 3. Power cycle the node
186
- 4. Verify timestamps remain accurate (±2 seconds)
187
-
188
- ### Verify NTP Sync
189
- 1. Connect bridge to Internet
190
- 2. Monitor serial output for sync messages
191
- 3. Verify RTC time updated correctly
192
-
193
- ### Verify Offline Operation
194
- 1. Disconnect Internet
195
- 2. Wait several hours
196
- 3. Verify timestamps continue to increment accurately
197
-
198
- ## Troubleshooting
199
-
200
- ### "Couldn't find RTC"
201
- - Check I2C connections (SDA/SCL)
202
- - Verify RTC module has power
203
- - Try I2C scanner sketch to detect device
204
-
205
- ### "RTC lost power"
206
- - RTC battery needs replacement
207
- - Time will be synced from NTP when available
208
-
209
- ### Time Not Syncing
210
- - Verify bridge has Internet connectivity
211
- - Check NTP server is accessible
212
- - Ensure `syncRTCFromNTP()` called with valid timestamp
213
-
214
- ## Time Authority
215
-
216
- painlessMesh v1.8.12+ includes **time authority** support to prevent nodes from adopting incorrect time from nodes without accurate time sources.
217
-
218
- ### How It Works
219
-
220
- Nodes with time authority (RTC or Internet) are prioritized during mesh time synchronization:
221
- - Nodes **without** time authority will adopt time from nodes **with** time authority
222
- - Nodes **with** time authority will **NOT** adopt time from nodes without
223
- - When both nodes have same authority status, existing subnet/node ID logic applies
224
-
225
- ### Setting Time Authority
226
-
227
- Time authority is automatically set when:
228
- - RTC is enabled via `enableRTC()` (time authority = true)
229
- - RTC is disabled via `disableRTC()` (time authority = false)
230
-
231
- For bridge nodes with Internet, set time authority manually:
232
-
233
- ```cpp
234
- void bridgeStatusCallback(uint32_t bridgeNodeId, bool hasInternet) {
235
- // If THIS node is the bridge, update time authority
236
- if (bridgeNodeId == mesh.getNodeId()) {
237
- if (hasInternet) {
238
- mesh.setTimeAuthority(true); // Internet available
239
- } else if (!mesh.hasRTC()) {
240
- mesh.setTimeAuthority(false); // No Internet and no RTC
241
- }
242
- }
243
- }
244
- ```
245
-
246
- ### Checking Time Authority
247
-
248
- ```cpp
249
- if (mesh.getTimeAuthority()) {
250
- Serial.println("This node has authoritative time source");
251
- }
252
- ```
253
-
254
- ### Use Cases
255
-
256
- **Scenario 1: Mixed RTC nodes**
257
- - Node A: Has RTC (time authority = true)
258
- - Node B: No RTC (time authority = false)
259
- - Result: Node B adopts time from Node A ✓
260
-
261
- **Scenario 2: Bridge with Internet**
262
- - Node A: Bridge with Internet (time authority = true)
263
- - Node B: Regular node (time authority = false)
264
- - Result: Node B adopts time from bridge ✓
265
-
266
- **Scenario 3: Network split**
267
- - Subnet A: All nodes have RTC
268
- - Subnet B: No nodes have RTC
269
- - Result: When subnets reconnect, Subnet B adopts from Subnet A ✓
270
-
271
- ## Best Practices
272
-
273
- 1. **Always check RTC availability** before relying on timestamps
274
- 2. **Sync regularly** when Internet available (recommended: every 24 hours)
275
- 3. **Monitor battery** on RTC modules for continuous operation
276
- 4. **Implement fallback** to mesh time if RTC fails
277
- 5. **Log sync events** for debugging and maintenance
278
- 6. **Set time authority** for bridge nodes when Internet is available
279
- 7. **Use RTC on at least one node** in offline deployments for accurate timestamps
280
-
281
- ## Regulatory Compliance
282
-
283
- For systems requiring timestamp accuracy (e.g., fish farm alarms):
284
-
285
- - RTC provides ±2 second accuracy during offline periods
286
- - Timestamps remain valid for alarm reporting
287
- - Sync logs provide audit trail
288
- - Battery backup ensures continuous operation
289
-
290
- ## See Also
291
-
292
- - [Bridge Status Feature](../../BRIDGE_STATUS_FEATURE.md) - Internet connectivity detection
293
- - [Bridge Architecture](../../BRIDGE_ARCHITECTURE_IMPLEMENTATION.md) - Mesh bridge setup
294
- - [painlessMesh Documentation](https://gitlab.com/painlessMesh/painlessMesh) - Main library docs
@@ -1,210 +0,0 @@
1
- //************************************************************
2
- // RTC Integration Example
3
- //
4
- // This example demonstrates how to use RTC (Real-Time Clock)
5
- // modules with painlessMesh for accurate offline timekeeping.
6
- //
7
- // When Internet/bridge is unavailable, nodes can still maintain
8
- // accurate timestamps using a local RTC module.
9
- //
10
- // Supported RTC modules:
11
- // - DS3231, DS1307 (I2C)
12
- // - PCF8523, PCF8563 (I2C)
13
- // - ESP32 internal RTC
14
- //
15
- // This example uses DS3231 with the RTClib library.
16
- // Install: https://github.com/adafruit/RTClib
17
- //************************************************************
18
-
19
- #include "painlessMesh.h"
20
- #include <RTClib.h> // Adafruit RTClib for DS3231
21
-
22
- #define MESH_PREFIX "AlteriomMesh"
23
- #define MESH_PASSWORD "somethingSneaky"
24
- #define MESH_PORT 5555
25
-
26
- Scheduler userScheduler;
27
- painlessMesh mesh;
28
-
29
- // DS3231 RTC instance
30
- RTC_DS3231 rtc;
31
-
32
- // RTC Interface implementation for DS3231
33
- class DS3231Interface : public painlessmesh::rtc::RTCInterface {
34
- private:
35
- RTC_DS3231* rtcDevice;
36
-
37
- public:
38
- DS3231Interface(RTC_DS3231* device) : rtcDevice(device) {}
39
-
40
- bool begin() override {
41
- if (!rtcDevice->begin()) {
42
- Serial.println("Couldn't find RTC");
43
- return false;
44
- }
45
-
46
- // Check if RTC lost power and needs time set
47
- if (rtcDevice->lostPower()) {
48
- Serial.println("RTC lost power, time needs to be set!");
49
- // Note: Time will be set via NTP when Internet available
50
- }
51
-
52
- return true;
53
- }
54
-
55
- bool isAvailable() override {
56
- return !rtcDevice->lostPower();
57
- }
58
-
59
- uint32_t getUnixTime() override {
60
- DateTime now = rtcDevice->now();
61
- return now.unixtime();
62
- }
63
-
64
- bool setUnixTime(uint32_t timestamp) override {
65
- rtcDevice->adjust(DateTime(timestamp));
66
- Serial.printf("RTC time set to: %u\n", timestamp);
67
- return true;
68
- }
69
-
70
- painlessmesh::rtc::RTCType getType() override {
71
- return painlessmesh::rtc::RTC_DS3231;
72
- }
73
- };
74
-
75
- // Create RTC interface instance
76
- DS3231Interface rtcInterface(&rtc);
77
-
78
- // Task to send timestamped sensor data
79
- void sendSensorData();
80
- Task taskSendData(30000, TASK_FOREVER, &sendSensorData);
81
-
82
- // Flag to track if we need NTP sync
83
- bool needsNTPSync = true;
84
-
85
- void setup() {
86
- Serial.begin(115200);
87
-
88
- // Initialize mesh
89
- mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
90
- mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
91
-
92
- // Set up mesh callbacks
93
- mesh.onReceive(&receivedCallback);
94
- mesh.onNewConnection(&newConnectionCallback);
95
- mesh.onChangedConnections(&changedConnectionCallback);
96
- mesh.onBridgeStatusChanged(&bridgeStatusCallback);
97
- mesh.onRTCSyncComplete(&rtcSyncCompleteCallback);
98
-
99
- // Enable RTC
100
- if (mesh.enableRTC(&rtcInterface)) {
101
- Serial.println("RTC enabled successfully!");
102
- Serial.printf("RTC Type: %d\n", mesh.getRTCType());
103
-
104
- // Print current RTC time
105
- uint32_t rtcTime = mesh.getAccurateTime();
106
- Serial.printf("Current RTC time: %u\n", rtcTime);
107
- } else {
108
- Serial.println("Failed to enable RTC - will use mesh time only");
109
- }
110
-
111
- // Add sensor data task
112
- userScheduler.addTask(taskSendData);
113
- taskSendData.enable();
114
-
115
- Serial.println("Setup complete");
116
- }
117
-
118
- void loop() {
119
- mesh.update();
120
- }
121
-
122
- void sendSensorData() {
123
- // Get accurate timestamp (RTC if available, mesh time otherwise)
124
- uint32_t timestamp = mesh.getAccurateTime();
125
-
126
- // Simulate sensor reading
127
- float temperature = 25.5 + random(-50, 50) / 10.0;
128
- float humidity = 60.0 + random(-100, 100) / 10.0;
129
-
130
- // Create message with timestamp
131
- String msg = "{\"type\":\"sensor\",";
132
- msg += "\"nodeId\":" + String(mesh.getNodeId()) + ",";
133
- msg += "\"timestamp\":" + String(timestamp) + ",";
134
- msg += "\"temperature\":" + String(temperature, 1) + ",";
135
- msg += "\"humidity\":" + String(humidity, 1) + ",";
136
- msg += "\"hasRTC\":" + String(mesh.hasRTC() ? "true" : "false") + ",";
137
- msg += "\"rtcType\":" + String(mesh.getRTCType());
138
- msg += "}";
139
-
140
- mesh.sendBroadcast(msg);
141
-
142
- Serial.printf("Sent sensor data with timestamp: %u\n", timestamp);
143
- Serial.printf("Time since last RTC sync: %u ms\n", mesh.getTimeSinceRTCSync());
144
- }
145
-
146
- void receivedCallback(uint32_t from, String &msg) {
147
- Serial.printf("Received from %u: %s\n", from, msg.c_str());
148
- }
149
-
150
- void newConnectionCallback(uint32_t nodeId) {
151
- Serial.printf("New Connection: %u\n", nodeId);
152
- }
153
-
154
- void changedConnectionCallback() {
155
- Serial.printf("Changed connections\n");
156
- }
157
-
158
- void bridgeStatusCallback(uint32_t bridgeNodeId, bool hasInternet) {
159
- Serial.printf("Bridge %u - Internet: %s\n",
160
- bridgeNodeId,
161
- hasInternet ? "Connected" : "Disconnected");
162
-
163
- // If THIS node is the bridge, set time authority based on Internet availability
164
- if (bridgeNodeId == mesh.getNodeId()) {
165
- if (hasInternet) {
166
- Serial.println("This node has Internet - setting time authority");
167
- mesh.setTimeAuthority(true);
168
- } else {
169
- // Lost Internet - remove time authority if no RTC
170
- if (!mesh.hasRTC()) {
171
- Serial.println("Lost Internet and no RTC - removing time authority");
172
- mesh.setTimeAuthority(false);
173
- }
174
- }
175
- }
176
-
177
- if (hasInternet && needsNTPSync && mesh.hasRTC()) {
178
- // Internet is available and we need to sync RTC
179
- // In a real application, you would get NTP time here
180
- // For this example, we'll use a placeholder
181
- Serial.println("Internet available - would sync RTC from NTP now");
182
-
183
- // Example: Get NTP time (you need to implement this)
184
- // uint32_t ntpTime = getNTPTime();
185
- // if (mesh.syncRTCFromNTP(ntpTime)) {
186
- // Serial.println("RTC synced successfully!");
187
- // needsNTPSync = false;
188
- // }
189
-
190
- // For demonstration purposes, let's sync to a known time
191
- uint32_t demoTime = 1704067200; // 2024-01-01 00:00:00 UTC
192
- if (mesh.syncRTCFromNTP(demoTime)) {
193
- Serial.println("RTC synced to demo time!");
194
- needsNTPSync = false;
195
- }
196
- } else if (!hasInternet) {
197
- // Internet lost - RTC will keep accurate time offline
198
- Serial.println("Internet offline - using RTC for timestamps");
199
- }
200
- }
201
-
202
- void rtcSyncCompleteCallback(uint32_t timestamp) {
203
- Serial.printf("RTC sync completed! New time: %u\n", timestamp);
204
-
205
- // Convert timestamp to human-readable format
206
- DateTime dt(timestamp);
207
- Serial.printf("Synced to: %d-%02d-%02d %02d:%02d:%02d\n",
208
- dt.year(), dt.month(), dt.day(),
209
- dt.hour(), dt.minute(), dt.second());
210
- }