@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.
- package/BRIDGE_TO_INTERNET.md +229 -0
- package/CHANGELOG.md +89 -1
- package/CONTRIBUTING.md +79 -0
- package/README.md +70 -143
- package/docs/README.md +1 -0
- package/docs/api/shared-gateway.md +1207 -0
- package/docs/troubleshooting/common-issues.md +28 -0
- package/docs/troubleshooting/faq.md +113 -12
- package/examples/basic/test/simulator/CMakeLists.txt +40 -0
- package/examples/basic/test/simulator/README.md +149 -0
- package/examples/basic/test/simulator/firmware/basic_firmware.hpp +117 -0
- package/examples/basic/test/simulator/scenarios/basic_mesh_test.yaml +81 -0
- package/examples/bridge/bridge.ino +17 -4
- package/examples/bridge_failover/README.md +81 -0
- package/examples/bridge_failover/bridge_failover.ino +51 -6
- package/examples/sharedGateway/README.md +235 -0
- package/examples/{meshCommandNode → sharedGateway}/platformio.ini +3 -2
- package/examples/sharedGateway/sharedGateway.ino +303 -0
- package/library.json +3 -22
- package/library.properties +1 -1
- package/package.json +3 -3
- package/src/arduino/wifi.hpp +380 -13
- package/src/painlessmesh/gateway.hpp +2120 -0
- package/src/painlessmesh/mesh.hpp +1034 -6
- package/src/painlessmesh/message_tracker.hpp +311 -0
- package/src/painlessmesh/protocol.hpp +6 -0
- package/DOCUMENTATION_INDEX.md +0 -146
- package/docs/API_DESIGN_GUIDELINES.md +0 -414
- package/docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md +0 -331
- package/docs/BOOLEAN_NAMING_CONVENTION.md +0 -235
- package/docs/BRIDGE_FAILOVER.md +0 -512
- package/docs/BRIDGE_HEALTH_MONITORING.md +0 -293
- package/docs/CHANNEL_SYNCHRONIZATION.md +0 -209
- package/docs/CREATE_MISSING_RELEASES.md +0 -321
- package/docs/DOCUMENTATION_MIGRATION_PLAN.md +0 -176
- package/docs/FAQ_VERSION_NUMBERS.md +0 -152
- package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +0 -1062
- package/docs/MESH_TOPOLOGY_GUIDE.md +0 -992
- package/docs/MESH_TOPOLOGY_PROGRESS.md +0 -422
- package/docs/MQTT_BRIDGE_COMMANDS.md +0 -894
- package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +0 -324
- package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +0 -576
- package/docs/MQTT_SCHEMA_COMPLIANCE.md +0 -340
- package/docs/MQTT_SCHEMA_PROPOSALS.md +0 -446
- package/docs/MQTT_SCHEMA_REVIEW.md +0 -690
- package/docs/OTA_COMMANDS_REFERENCE.md +0 -554
- package/docs/PHASE1_GUIDE.md +0 -349
- package/docs/PHASE2_GUIDE.md +0 -543
- package/docs/QUICK_REFERENCE_VERSIONING.md +0 -127
- package/docs/RELEASE_AGENT_SUMMARY.md +0 -386
- package/docs/SCHEMA_VALIDATION_CHECKLIST.md +0 -222
- package/docs/VERSION_MANAGEMENT.md +0 -213
- package/docs/archive/DOCUSAURUS_DEPLOYMENT.md +0 -166
- package/docs/archive/FEATURE_PROPOSALS.md +0 -337
- package/docs/archive/LIBRARY_JSON_FIX.md +0 -98
- package/docs/archive/LIBRARY_STRUCTURE_FIX.md +0 -215
- package/docs/archive/PHASE1_IMPLEMENTATION.md +0 -325
- package/docs/archive/PHASE2_IMPLEMENTATION.md +0 -567
- package/docs/archive/RELEASE_SUMMARY.md +0 -173
- package/docs/archive/SCONS_BUILD_FIX.md +0 -313
- package/docs/archive/TRIGGER_RELEASE.md +0 -280
- package/docs/archive/VECTOR_INCLUDE_FIX.md +0 -129
- package/docs/archive/ota-and-status-enhancements.md +0 -911
- package/docs/archive/ota-status-architecture-diagrams.md +0 -658
- package/docs/archive/ota-status-quick-reference.md +0 -284
- package/docs/design/.gitkeep +0 -1
- package/docs/design/STATION_CREDENTIALS_DESIGN.md +0 -182
- package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +0 -71
- package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +0 -1011
- package/docs/development/DOCKER_TESTING.md +0 -196
- package/docs/development/PLATFORMIO_USAGE.md +0 -180
- package/docs/development/TESTING_SUMMARY.md +0 -126
- package/docs/development/contributing.md +0 -301
- package/docs/development/documentation.md +0 -583
- package/docs/features/DIAGNOSTICS_API.md +0 -534
- package/docs/implementation/BRIDGE_ARCHITECTURE_IMPLEMENTATION.md +0 -340
- package/docs/implementation/BRIDGE_HEALTH_MONITORING_IMPLEMENTATION.md +0 -213
- package/docs/implementation/BRIDGE_STATUS_FEATURE.md +0 -635
- package/docs/implementation/DIAGNOSTICS_API_IMPLEMENTATION.md +0 -232
- package/docs/implementation/IMPLEMENTATION_COMPLETE.md +0 -228
- package/docs/implementation/IMPLEMENTATION_NTP_TIME_SYNC.md +0 -325
- package/docs/implementation/IMPLEMENTATION_SUMMARY.md +0 -316
- package/docs/implementation/MESSAGE_QUEUE_IMPLEMENTATION.md +0 -405
- package/docs/implementation/MULTI_BRIDGE_IMPLEMENTATION.md +0 -520
- package/docs/implementation/NTP_TIME_SYNC_FEATURE.md +0 -392
- package/docs/improvements/FUTURE_PROPOSALS.md +0 -1016
- package/docs/improvements/IMPLEMENTATION_HISTORY.md +0 -1091
- package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +0 -709
- package/docs/improvements/README.md +0 -212
- package/docs/internal/CUSTOM_AGENT_ANALYSIS.md +0 -391
- package/docs/internal/ISSUE_65_VERIFICATION.md +0 -947
- package/docs/internal/ISSUE_66_CLOSURE.md +0 -249
- package/docs/internal/ISSUE_66_STATUS.md +0 -316
- package/docs/internal/PR_SUMMARY.md +0 -315
- package/docs/internal/REVIEW_SUMMARY.md +0 -332
- package/docs/multi-bridge-setup.md +0 -1025
- package/docs/platformio-publishing.md +0 -255
- package/docs/platformio-setup-summary.md +0 -121
- package/docs/releases/ANNOUNCEMENT_v1.8.6.md +0 -63
- package/docs/releases/ANNOUNCEMENT_v1.8.7.md +0 -113
- package/docs/releases/BRIDGE_STATUS_SELF_REGISTRATION_FIX.md +0 -221
- package/docs/releases/FEATURE_HISTORY.md +0 -543
- package/docs/releases/GITHUB_RELEASE_v1.8.6.md +0 -71
- package/docs/releases/GITHUB_RELEASE_v1.8.7.md +0 -90
- package/docs/releases/PATCH_v1.7.2.md +0 -262
- package/docs/releases/PATCH_v1.7.3.md +0 -262
- package/docs/releases/PATCH_v1.7.4.md +0 -219
- package/docs/releases/PHASE1_SUMMARY.md +0 -246
- package/docs/releases/PHASE2_SUMMARY.md +0 -499
- package/docs/releases/PUBLISH_v1.8.0_INSTRUCTIONS.md +0 -163
- package/docs/releases/QUICK_START_RELEASES.md +0 -113
- package/docs/releases/RELEASE_CHECKLIST_1.8.10.md +0 -331
- package/docs/releases/RELEASE_CHECKLIST_1.8.9.md +0 -207
- package/docs/releases/RELEASE_CHECKLIST_v1.7.4.md +0 -253
- package/docs/releases/RELEASE_CHECKLIST_v1.7.5.md +0 -315
- package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +0 -389
- package/docs/releases/RELEASE_CHECKLIST_v1.8.0.md +0 -331
- package/docs/releases/RELEASE_CHECKLIST_v1.8.2.md +0 -309
- package/docs/releases/RELEASE_NOTES_1.7.0.md +0 -539
- package/docs/releases/RELEASE_NOTES_1.8.10.md +0 -239
- package/docs/releases/RELEASE_NOTES_1.8.9.md +0 -213
- package/docs/releases/RELEASE_NOTES_v1.8.0.md +0 -685
- package/docs/releases/RELEASE_NOTES_v1.8.1.md +0 -221
- package/docs/releases/RELEASE_NOTES_v1.8.2.md +0 -421
- package/docs/releases/RELEASE_NOTES_v1.8.3.md +0 -292
- package/docs/releases/RELEASE_NOTES_v1.8.4.md +0 -277
- package/docs/releases/RELEASE_NOTES_v1.8.6.md +0 -205
- package/docs/releases/RELEASE_NOTES_v1.8.7.md +0 -184
- package/docs/releases/RELEASE_PLAN_v1.7.6.md +0 -816
- package/docs/releases/RELEASE_SUMMARY_1.8.10.md +0 -193
- package/docs/releases/RELEASE_SUMMARY_v1.7.4.md +0 -276
- package/docs/releases/RELEASE_SUMMARY_v1.7.5.md +0 -322
- package/docs/releases/RELEASE_SUMMARY_v1.7.6.md +0 -436
- package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +0 -391
- package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +0 -523
- package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +0 -542
- package/docs/troubleshooting/ARDUINO_IDE_VERSION_FIX_SUMMARY.md +0 -229
- package/docs/troubleshooting/ARDUINO_LIBRARY_NAME_FIX.md +0 -197
- package/docs/troubleshooting/CRASH_QUICK_REF.md +0 -93
- package/docs/troubleshooting/ESP32_C6_COMPATIBILITY.md +0 -157
- package/docs/troubleshooting/FREERTOS_ASSERTION_FAILURE.md +0 -288
- package/docs/troubleshooting/FREERTOS_FIX_IMPLEMENTATION.md +0 -267
- package/docs/troubleshooting/NPM_PUBLISHING_ISSUE_SUMMARY.md +0 -110
- package/docs/troubleshooting/PAINLESSMESH_V1.7.4_COMPILATION_ISSUES.md +0 -547
- package/docs/troubleshooting/QUICK_FIX_FREERTOS.md +0 -164
- package/docs/troubleshooting/SENSOR_NODE_CONNECTION_CRASH.md +0 -264
- package/docs/troubleshooting/station-reconnection-issues.md +0 -172
- package/docs/v1.7.7_MQTT_IMPROVEMENTS.md +0 -794
- package/docs/wiki/API-Reference.md +0 -246
- package/docs/wiki/Complete-Documentation.md +0 -123
- package/examples/alteriomImproved/alteriom_sensor_package.hpp +0 -224
- package/examples/alteriomImproved/improved_sensor_node.ino +0 -248
- package/examples/alteriomImproved/platformio.ini +0 -32
- package/examples/alteriomMetricsHealth/alteriom_sensor_package.hpp +0 -796
- package/examples/alteriomMetricsHealth/metrics_health_node.ino +0 -429
- package/examples/alteriomMetricsHealth/platformio.ini +0 -26
- package/examples/alteriomPhase1/alteriom_sensor_package.hpp +0 -224
- package/examples/alteriomPhase1/phase1_features.ino +0 -242
- package/examples/alteriomPhase1/platformio.ini +0 -26
- package/examples/alteriomPhase2/alteriom_sensor_package.hpp +0 -224
- package/examples/alteriomPhase2/phase2_features.ino +0 -186
- package/examples/alteriomPhase2/platformio.ini +0 -26
- package/examples/alteriomSensorNode/alteriom_sensor_node.ino +0 -186
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +0 -1227
- package/examples/alteriomSensorNode/platformio.ini +0 -26
- package/examples/bridge/alteriom_sensor_package.hpp +0 -1170
- package/examples/bridge/bridge_health_monitoring_example.ino +0 -188
- package/examples/bridge/enhanced_mqtt_bridge.hpp +0 -610
- package/examples/bridge/enhanced_mqtt_bridge_example.ino +0 -226
- package/examples/bridge/mesh_event_publisher.hpp +0 -253
- package/examples/bridge/mesh_topology_reporter.hpp +0 -303
- package/examples/bridge/mqtt_command_bridge.hpp +0 -459
- package/examples/bridge/mqtt_status_bridge.hpp +0 -519
- package/examples/bridgeAwareSensorNode/alteriom_sensor_package.hpp +0 -1227
- package/examples/bridgeAwareSensorNode/bridgeAwareSensorNode.ino +0 -342
- package/examples/bridgeAwareSensorNode/platformio.ini +0 -26
- package/examples/diagnosticsExample/diagnosticsExample.ino +0 -171
- package/examples/diagnosticsExample/platformio.ini +0 -26
- package/examples/echoNode/echoNode.ino +0 -33
- package/examples/echoNode/platformio.ini +0 -26
- package/examples/meshCommandNode/alteriom_sensor_package.hpp +0 -235
- package/examples/meshCommandNode/meshCommandNode.ino +0 -265
- package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +0 -235
- package/examples/mqttCommandBridge/mesh_event_publisher.hpp +0 -253
- package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +0 -303
- package/examples/mqttCommandBridge/mqttCommandBridge.ino +0 -254
- package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +0 -462
- package/examples/mqttCommandBridge/platformio.ini +0 -27
- package/examples/mqttStatusBridge/mqttStatusBridge.ino +0 -218
- package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +0 -522
- package/examples/mqttStatusBridge/platformio.ini +0 -27
- package/examples/mqttTopologyTest/README.md +0 -467
- package/examples/mqttTopologyTest/mqttTopologyTest.ino +0 -754
- package/examples/mqttTopologyTest/platformio.ini +0 -27
- package/examples/multi_bridge/README.md +0 -346
- package/examples/multi_bridge/primary_bridge.ino +0 -96
- package/examples/multi_bridge/regular_node.ino +0 -141
- package/examples/multi_bridge/secondary_bridge.ino +0 -111
- package/examples/ntpTimeSyncBridge/alteriom_sensor_package.hpp +0 -1383
- package/examples/ntpTimeSyncBridge/ntpTimeSyncBridge.ino +0 -86
- package/examples/ntpTimeSyncNode/alteriom_sensor_package.hpp +0 -1383
- package/examples/ntpTimeSyncNode/ntpTimeSyncNode.ino +0 -109
- package/examples/queued_alarms/README.md +0 -390
- package/examples/queued_alarms/queued_alarms.ino +0 -265
- package/examples/routing_demo/README.md +0 -172
- package/examples/routing_demo/routing_demo.ino +0 -102
- package/examples/rtcIntegration/README.md +0 -294
- 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
|
-
}
|