@alteriom/painlessmesh 1.8.15 → 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 +61 -1
  3. package/CONTRIBUTING.md +79 -0
  4. package/README.md +69 -144
  5. package/docs/README.md +1 -0
  6. package/docs/api/shared-gateway.md +1207 -0
  7. package/examples/bridge_failover/README.md +81 -0
  8. package/examples/bridge_failover/bridge_failover.ino +35 -4
  9. package/examples/sharedGateway/README.md +235 -0
  10. package/examples/{meshCommandNode → sharedGateway}/platformio.ini +3 -2
  11. package/examples/sharedGateway/sharedGateway.ino +303 -0
  12. package/library.json +3 -22
  13. package/library.properties +1 -1
  14. package/package.json +3 -6
  15. package/src/arduino/wifi.hpp +342 -4
  16. package/src/painlessmesh/gateway.hpp +2120 -0
  17. package/src/painlessmesh/mesh.hpp +1034 -6
  18. package/src/painlessmesh/message_tracker.hpp +311 -0
  19. package/src/painlessmesh/protocol.hpp +6 -0
  20. package/DOCUMENTATION_INDEX.md +0 -146
  21. package/RELEASE_NOTES_1.8.15.md +0 -160
  22. package/RELEASE_READINESS_PLAN.md +0 -323
  23. package/TESTING_WITH_SIMULATOR.md +0 -259
  24. package/docs/API_DESIGN_GUIDELINES.md +0 -414
  25. package/docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md +0 -331
  26. package/docs/BOOLEAN_NAMING_CONVENTION.md +0 -235
  27. package/docs/BRIDGE_FAILOVER.md +0 -512
  28. package/docs/BRIDGE_HEALTH_MONITORING.md +0 -293
  29. package/docs/BRIDGE_INITIALIZATION_FALLBACK.md +0 -357
  30. package/docs/CHANNEL_SYNCHRONIZATION.md +0 -209
  31. package/docs/CREATE_MISSING_RELEASES.md +0 -321
  32. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +0 -176
  33. package/docs/FAQ_VERSION_NUMBERS.md +0 -152
  34. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +0 -1062
  35. package/docs/MESH_TOPOLOGY_GUIDE.md +0 -992
  36. package/docs/MESH_TOPOLOGY_PROGRESS.md +0 -422
  37. package/docs/MQTT_BRIDGE_COMMANDS.md +0 -894
  38. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +0 -324
  39. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +0 -576
  40. package/docs/MQTT_SCHEMA_COMPLIANCE.md +0 -340
  41. package/docs/MQTT_SCHEMA_PROPOSALS.md +0 -446
  42. package/docs/MQTT_SCHEMA_REVIEW.md +0 -690
  43. package/docs/OTA_COMMANDS_REFERENCE.md +0 -554
  44. package/docs/PHASE1_GUIDE.md +0 -349
  45. package/docs/PHASE2_GUIDE.md +0 -543
  46. package/docs/QUICK_REFERENCE_VERSIONING.md +0 -127
  47. package/docs/RELEASE_AGENT_SUMMARY.md +0 -386
  48. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +0 -222
  49. package/docs/SIMULATOR_TESTING.md +0 -408
  50. package/docs/VERSION_MANAGEMENT.md +0 -213
  51. package/docs/archive/DOCUSAURUS_DEPLOYMENT.md +0 -166
  52. package/docs/archive/FEATURE_PROPOSALS.md +0 -337
  53. package/docs/archive/LIBRARY_JSON_FIX.md +0 -98
  54. package/docs/archive/LIBRARY_STRUCTURE_FIX.md +0 -215
  55. package/docs/archive/PHASE1_IMPLEMENTATION.md +0 -325
  56. package/docs/archive/PHASE2_IMPLEMENTATION.md +0 -567
  57. package/docs/archive/RELEASE_SUMMARY.md +0 -173
  58. package/docs/archive/SCONS_BUILD_FIX.md +0 -313
  59. package/docs/archive/TRIGGER_RELEASE.md +0 -280
  60. package/docs/archive/VECTOR_INCLUDE_FIX.md +0 -129
  61. package/docs/archive/ota-and-status-enhancements.md +0 -911
  62. package/docs/archive/ota-status-architecture-diagrams.md +0 -658
  63. package/docs/archive/ota-status-quick-reference.md +0 -284
  64. package/docs/design/.gitkeep +0 -1
  65. package/docs/design/STATION_CREDENTIALS_DESIGN.md +0 -182
  66. package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +0 -71
  67. package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +0 -1011
  68. package/docs/development/DOCKER_TESTING.md +0 -196
  69. package/docs/development/PLATFORMIO_USAGE.md +0 -180
  70. package/docs/development/TESTING_SUMMARY.md +0 -126
  71. package/docs/development/contributing.md +0 -301
  72. package/docs/development/documentation.md +0 -583
  73. package/docs/features/DIAGNOSTICS_API.md +0 -534
  74. package/docs/implementation/BRIDGE_ARCHITECTURE_IMPLEMENTATION.md +0 -340
  75. package/docs/implementation/BRIDGE_HEALTH_MONITORING_IMPLEMENTATION.md +0 -213
  76. package/docs/implementation/BRIDGE_STATUS_FEATURE.md +0 -635
  77. package/docs/implementation/DIAGNOSTICS_API_IMPLEMENTATION.md +0 -232
  78. package/docs/implementation/IMPLEMENTATION_COMPLETE.md +0 -228
  79. package/docs/implementation/IMPLEMENTATION_NTP_TIME_SYNC.md +0 -325
  80. package/docs/implementation/IMPLEMENTATION_SUMMARY.md +0 -316
  81. package/docs/implementation/MESSAGE_QUEUE_IMPLEMENTATION.md +0 -405
  82. package/docs/implementation/MULTI_BRIDGE_IMPLEMENTATION.md +0 -520
  83. package/docs/implementation/NTP_TIME_SYNC_FEATURE.md +0 -392
  84. package/docs/improvements/FUTURE_PROPOSALS.md +0 -1016
  85. package/docs/improvements/IMPLEMENTATION_HISTORY.md +0 -1091
  86. package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +0 -709
  87. package/docs/improvements/README.md +0 -212
  88. package/docs/internal/CUSTOM_AGENT_ANALYSIS.md +0 -391
  89. package/docs/internal/ISSUE_65_VERIFICATION.md +0 -947
  90. package/docs/internal/ISSUE_66_CLOSURE.md +0 -249
  91. package/docs/internal/ISSUE_66_STATUS.md +0 -316
  92. package/docs/internal/PR_SUMMARY.md +0 -315
  93. package/docs/internal/REVIEW_SUMMARY.md +0 -332
  94. package/docs/multi-bridge-setup.md +0 -1025
  95. package/docs/platformio-publishing.md +0 -255
  96. package/docs/platformio-setup-summary.md +0 -121
  97. package/docs/releases/ANNOUNCEMENT_v1.8.6.md +0 -63
  98. package/docs/releases/ANNOUNCEMENT_v1.8.7.md +0 -113
  99. package/docs/releases/BRIDGE_STATUS_SELF_REGISTRATION_FIX.md +0 -221
  100. package/docs/releases/FEATURE_HISTORY.md +0 -543
  101. package/docs/releases/GITHUB_RELEASE_v1.8.6.md +0 -71
  102. package/docs/releases/GITHUB_RELEASE_v1.8.7.md +0 -90
  103. package/docs/releases/PATCH_v1.7.2.md +0 -262
  104. package/docs/releases/PATCH_v1.7.3.md +0 -262
  105. package/docs/releases/PATCH_v1.7.4.md +0 -219
  106. package/docs/releases/PHASE1_SUMMARY.md +0 -246
  107. package/docs/releases/PHASE2_SUMMARY.md +0 -499
  108. package/docs/releases/PUBLISH_v1.8.0_INSTRUCTIONS.md +0 -163
  109. package/docs/releases/QUICK_START_RELEASES.md +0 -113
  110. package/docs/releases/RELEASE_CHECKLIST_1.8.10.md +0 -331
  111. package/docs/releases/RELEASE_CHECKLIST_1.8.9.md +0 -207
  112. package/docs/releases/RELEASE_CHECKLIST_v1.7.4.md +0 -253
  113. package/docs/releases/RELEASE_CHECKLIST_v1.7.5.md +0 -315
  114. package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +0 -389
  115. package/docs/releases/RELEASE_CHECKLIST_v1.8.0.md +0 -331
  116. package/docs/releases/RELEASE_CHECKLIST_v1.8.2.md +0 -309
  117. package/docs/releases/RELEASE_NOTES_1.7.0.md +0 -539
  118. package/docs/releases/RELEASE_NOTES_1.8.10.md +0 -239
  119. package/docs/releases/RELEASE_NOTES_1.8.9.md +0 -213
  120. package/docs/releases/RELEASE_NOTES_v1.8.0.md +0 -685
  121. package/docs/releases/RELEASE_NOTES_v1.8.1.md +0 -221
  122. package/docs/releases/RELEASE_NOTES_v1.8.2.md +0 -421
  123. package/docs/releases/RELEASE_NOTES_v1.8.3.md +0 -292
  124. package/docs/releases/RELEASE_NOTES_v1.8.4.md +0 -277
  125. package/docs/releases/RELEASE_NOTES_v1.8.6.md +0 -205
  126. package/docs/releases/RELEASE_NOTES_v1.8.7.md +0 -184
  127. package/docs/releases/RELEASE_PLAN_v1.7.6.md +0 -816
  128. package/docs/releases/RELEASE_SUMMARY_1.8.10.md +0 -193
  129. package/docs/releases/RELEASE_SUMMARY_v1.7.4.md +0 -276
  130. package/docs/releases/RELEASE_SUMMARY_v1.7.5.md +0 -322
  131. package/docs/releases/RELEASE_SUMMARY_v1.7.6.md +0 -436
  132. package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +0 -391
  133. package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +0 -523
  134. package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +0 -542
  135. package/docs/troubleshooting/ARDUINO_IDE_VERSION_FIX_SUMMARY.md +0 -229
  136. package/docs/troubleshooting/ARDUINO_LIBRARY_NAME_FIX.md +0 -197
  137. package/docs/troubleshooting/CRASH_QUICK_REF.md +0 -93
  138. package/docs/troubleshooting/ESP32_C6_COMPATIBILITY.md +0 -157
  139. package/docs/troubleshooting/FREERTOS_ASSERTION_FAILURE.md +0 -288
  140. package/docs/troubleshooting/FREERTOS_FIX_IMPLEMENTATION.md +0 -267
  141. package/docs/troubleshooting/NPM_PUBLISHING_ISSUE_SUMMARY.md +0 -110
  142. package/docs/troubleshooting/PAINLESSMESH_V1.7.4_COMPILATION_ISSUES.md +0 -547
  143. package/docs/troubleshooting/QUICK_FIX_FREERTOS.md +0 -164
  144. package/docs/troubleshooting/SENSOR_NODE_CONNECTION_CRASH.md +0 -264
  145. package/docs/troubleshooting/common-architecture-mistakes.md +0 -438
  146. package/docs/troubleshooting/internet-access-faq.md +0 -299
  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 -108
  197. package/examples/multi_bridge/regular_node.ino +0 -141
  198. package/examples/multi_bridge/secondary_bridge.ino +0 -123
  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
- }