@alteriom/painlessmesh 1.8.2 → 1.8.3

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 (49) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +62 -11
  3. package/RELEASE_GUIDE.md +57 -16
  4. package/docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md +331 -0
  5. package/docs/features/DIAGNOSTICS_API.md +534 -0
  6. package/docs/getting-started/arduino-manual-install.md +313 -0
  7. package/docs/implementation/BRIDGE_ARCHITECTURE_IMPLEMENTATION.md +340 -0
  8. package/docs/implementation/BRIDGE_HEALTH_MONITORING_IMPLEMENTATION.md +213 -0
  9. package/docs/implementation/BRIDGE_STATUS_FEATURE.md +635 -0
  10. package/docs/implementation/DIAGNOSTICS_API_IMPLEMENTATION.md +232 -0
  11. package/docs/implementation/IMPLEMENTATION_COMPLETE.md +228 -0
  12. package/docs/implementation/IMPLEMENTATION_NTP_TIME_SYNC.md +325 -0
  13. package/docs/implementation/IMPLEMENTATION_SUMMARY.md +316 -0
  14. package/docs/implementation/MESSAGE_QUEUE_IMPLEMENTATION.md +405 -0
  15. package/docs/implementation/MULTI_BRIDGE_IMPLEMENTATION.md +520 -0
  16. package/docs/implementation/NTP_TIME_SYNC_FEATURE.md +392 -0
  17. package/docs/internal/CUSTOM_AGENT_ANALYSIS.md +391 -0
  18. package/docs/internal/ISSUE_65_VERIFICATION.md +947 -0
  19. package/docs/internal/ISSUE_66_CLOSURE.md +249 -0
  20. package/docs/internal/ISSUE_66_STATUS.md +316 -0
  21. package/docs/internal/PR_SUMMARY.md +315 -0
  22. package/docs/internal/REVIEW_SUMMARY.md +332 -0
  23. package/docs/releases/PUBLISH_v1.8.0_INSTRUCTIONS.md +163 -0
  24. package/docs/releases/QUICK_START_RELEASES.md +113 -0
  25. package/docs/releases/RELEASE_CHECKLIST_v1.8.0.md +331 -0
  26. package/docs/releases/RELEASE_CHECKLIST_v1.8.2.md +309 -0
  27. package/docs/releases/RELEASE_NOTES_v1.8.0.md +685 -0
  28. package/docs/releases/RELEASE_NOTES_v1.8.1.md +221 -0
  29. package/docs/releases/RELEASE_NOTES_v1.8.2.md +421 -0
  30. package/docs/releases/RELEASE_NOTES_v1.8.3.md +292 -0
  31. package/docs/troubleshooting/ARDUINO_IDE_VERSION_FIX_SUMMARY.md +229 -0
  32. package/docs/troubleshooting/ARDUINO_LIBRARY_NAME_FIX.md +197 -0
  33. package/docs/troubleshooting/NPM_PUBLISHING_ISSUE_SUMMARY.md +110 -0
  34. package/docs/troubleshooting/station-reconnection-issues.md +172 -0
  35. package/examples/priority/README.md +274 -0
  36. package/examples/priority/priority_basic_example.ino +115 -0
  37. package/examples/priority/priority_with_queue.ino +249 -0
  38. package/examples/routing_demo/README.md +172 -0
  39. package/examples/routing_demo/routing_demo.ino +102 -0
  40. package/library.json +1 -1
  41. package/library.properties +3 -3
  42. package/package.json +1 -1
  43. package/src/arduino/wifi.hpp +49 -16
  44. package/src/painlessMesh.h +15 -0
  45. package/src/painlessMeshSTA.cpp +7 -1
  46. package/src/painlessmesh/buffer.hpp +218 -37
  47. package/src/painlessmesh/connection.hpp +21 -1
  48. package/src/painlessmesh/mesh.hpp +253 -19
  49. package/src/painlessmesh/router.hpp +31 -0
@@ -0,0 +1,197 @@
1
+ # Arduino Library Manager - Library Name Fix
2
+
3
+ ## Issue Resolution Summary
4
+
5
+ **Date**: November 11, 2025
6
+ **Issue**: Arduino IDE showing version 1.6.1 instead of current version 1.8.2
7
+ **Status**: ✅ **RESOLVED**
8
+
9
+ ## Problem Analysis
10
+
11
+ ### Initial Diagnosis (Incorrect)
12
+ Initially believed the library was not registered in Arduino Library Manager.
13
+
14
+ ### Actual Root Cause (Correct)
15
+ The library IS registered, but the library name changed between releases:
16
+
17
+ | Version | Library Name | Arduino Indexing |
18
+ |---------|-------------|------------------|
19
+ | v1.6.1 (Sept 2025) | `Alteriom PainlessMesh` | ✅ Indexed |
20
+ | v1.7.0 - v1.8.2 | `AlteriomPainlessMesh` | ❌ Not indexed |
21
+
22
+ **Arduino Library Manager Requirement**: Library names must remain consistent after registration.
23
+
24
+ When the name changed from `Alteriom PainlessMesh` (with space) to `AlteriomPainlessMesh` (no space), the Arduino indexer stopped recognizing new releases as updates to the registered library.
25
+
26
+ ## Solution Applied
27
+
28
+ ### Change Made
29
+ Restored the library name in `library.properties` to match the original registration:
30
+
31
+ ```diff
32
+ - name=AlteriomPainlessMesh
33
+ + name=Alteriom PainlessMesh
34
+ ```
35
+
36
+ ### Verification
37
+ ```bash
38
+ # v1.6.1 (last indexed version)
39
+ name=Alteriom PainlessMesh
40
+
41
+ # Current (fixed)
42
+ name=Alteriom PainlessMesh
43
+
44
+ # Result: ✓ Names match
45
+ ```
46
+
47
+ ## Impact & Timeline
48
+
49
+ ### Immediate
50
+ - ✅ Library name corrected in repository
51
+ - ✅ Validation script updated to detect this issue
52
+ - ✅ Documentation updated with correct information
53
+
54
+ ### Next 24-48 Hours
55
+ - Arduino Library Manager will detect next release (v1.8.3 or v1.9.0)
56
+ - New version will appear in Arduino IDE Library Manager
57
+ - Users will see update notification
58
+
59
+ ### Going Forward
60
+ - All future releases will be automatically indexed
61
+ - No manual intervention required
62
+ - Library Manager will show latest versions within 24-48 hours of each GitHub release
63
+
64
+ ## Technical Details
65
+
66
+ ### Arduino Library Registry Status
67
+ - **Registered**: ✅ Yes
68
+ - **Repository URL**: https://github.com/Alteriom/painlessMesh
69
+ - **Registry Entry**: https://github.com/arduino/library-registry (repositories.txt)
70
+ - **Original Registration Name**: `Alteriom PainlessMesh`
71
+
72
+ ### How Arduino Library Manager Works
73
+ 1. Library is registered once in arduino/library-registry
74
+ 2. Arduino indexer checks registered repositories for new releases every 24-48 hours
75
+ 3. For each new release tag, indexer reads `library.properties`
76
+ 4. **Critical**: Library name in `library.properties` must match original registration
77
+ 5. If name matches, new version is added to index
78
+ 6. If name doesn't match, release is ignored
79
+
80
+ ### Why Name Changed
81
+ Between v1.6.1 and v1.7.0, the library name was changed (likely to remove the space for URL compatibility). However, this broke Arduino Library Manager indexing.
82
+
83
+ ### Versions Affected
84
+ **Not Indexed** (due to name mismatch):
85
+ - v1.7.0, v1.7.1, v1.7.2, v1.7.3, v1.7.4, v1.7.5, v1.7.6, v1.7.7, v1.7.8, v1.7.9
86
+ - v1.8.0, v1.8.1, v1.8.2
87
+
88
+ **Will Be Indexed** (after fix):
89
+ - v1.8.3+ (any future releases with corrected name)
90
+
91
+ ## What Users Will See
92
+
93
+ ### Before Fix
94
+ ```
95
+ Arduino IDE Library Manager:
96
+ ┌─────────────────────────────────┐
97
+ │ Alteriom PainlessMesh │
98
+ │ Version: 1.6.1 │
99
+ │ [Installed] │
100
+ └─────────────────────────────────┘
101
+ ```
102
+
103
+ ### After Fix (24-48 hours after v1.8.3 release)
104
+ ```
105
+ Arduino IDE Library Manager:
106
+ ┌─────────────────────────────────┐
107
+ │ Alteriom PainlessMesh │
108
+ │ Version: 1.8.3 (Update available)│
109
+ │ [Update] │
110
+ └─────────────────────────────────┘
111
+ ```
112
+
113
+ ## Validation
114
+
115
+ ### Automated Check
116
+ Run the validation script to confirm library name is correct:
117
+
118
+ ```bash
119
+ ./scripts/validate-arduino-compliance.sh
120
+ ```
121
+
122
+ Expected output:
123
+ ```
124
+ Checking library name format... ✓ CORRECT (name='Alteriom PainlessMesh')
125
+ ```
126
+
127
+ ### Manual Verification
128
+ Compare current name with v1.6.1:
129
+
130
+ ```bash
131
+ # Current
132
+ grep "^name=" library.properties
133
+ # Output: name=Alteriom PainlessMesh
134
+
135
+ # v1.6.1 (last indexed)
136
+ curl -s "https://raw.githubusercontent.com/Alteriom/painlessMesh/v1.6.1/library.properties" | grep "^name="
137
+ # Output: name=Alteriom PainlessMesh
138
+
139
+ # They should match ✓
140
+ ```
141
+
142
+ ## Lessons Learned
143
+
144
+ ### For Library Maintainers
145
+ 1. **Never change library name** after Arduino Library Manager registration
146
+ 2. Library name must remain exactly the same (including spaces, capitalization)
147
+ 3. Use validation scripts to catch name changes before release
148
+ 4. Check Arduino Library Manager indexing after each release
149
+
150
+ ### For This Repository
151
+ 1. Added library name validation to compliance script
152
+ 2. Documented the requirement clearly in release guide
153
+ 3. This issue is now prevented by automated checks
154
+
155
+ ## Related Files
156
+
157
+ ### Modified Files (Commit 5065fa5)
158
+ - `library.properties` - Restored correct library name
159
+ - `docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md` - Updated with resolution
160
+ - `README.md` - Fixed status and explanation
161
+ - `RELEASE_GUIDE.md` - Corrected registration information
162
+ - `ARDUINO_IDE_VERSION_FIX_SUMMARY.md` - Updated resolution details
163
+ - `scripts/validate-arduino-compliance.sh` - Added name consistency check
164
+
165
+ ### Documentation
166
+ - `docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md` - Complete guide
167
+ - `ARDUINO_IDE_VERSION_FIX_SUMMARY.md` - Issue summary
168
+ - This file - Detailed resolution documentation
169
+
170
+ ## References
171
+
172
+ ### Arduino Documentation
173
+ - [Arduino Library Manager FAQ](https://github.com/arduino/library-registry/blob/main/FAQ.md)
174
+ - [Library Specification](https://arduino.github.io/arduino-cli/latest/library-specification/)
175
+ - [Why libraries aren't updated](https://github.com/arduino/library-registry/issues/1002)
176
+
177
+ ### Repository Links
178
+ - [Arduino Library Registry](https://github.com/arduino/library-registry)
179
+ - [Library Registry repositories.txt](https://github.com/arduino/library-registry/blob/main/repositories.txt)
180
+ - [This Repository](https://github.com/Alteriom/painlessMesh)
181
+
182
+ ## Credits
183
+
184
+ **Issue Identified By**: @sparck75
185
+ **Resolution**: GitHub Copilot
186
+ **Date**: November 11, 2025
187
+ **Commit**: 5065fa5
188
+
189
+ ---
190
+
191
+ ## Summary
192
+
193
+ ✅ **Issue**: Library name changed, breaking Arduino indexing
194
+ ✅ **Fix**: Restored original name with space
195
+ ✅ **Result**: Automatic indexing will resume with next release
196
+ ✅ **Timeline**: 24-48 hours after v1.8.3+ release
197
+ ✅ **Prevention**: Validation script now checks library name
@@ -0,0 +1,110 @@
1
+ # NPM and GitHub Packages Publishing Issue - Summary
2
+
3
+ ## Issue Identified
4
+
5
+ When PR#19 was merged to main with the commit message:
6
+ ```
7
+ Release v1.7.7 - Complete mqtt-schema v0.7.2 implementation
8
+ ```
9
+
10
+ The automated release workflow created the tag and GitHub release successfully, **but the NPM and GitHub Packages publishing jobs were skipped**.
11
+
12
+ ## Root Cause
13
+
14
+ The automated workflow file `.github/workflows/release.yml` has a condition for NPM and GitHub Packages publishing:
15
+
16
+ ```yaml
17
+ npm-publish:
18
+ needs: [tag-and-release]
19
+ runs-on: ubuntu-latest
20
+ if: startsWith(github.event.head_commit.message, 'release:')
21
+ ```
22
+
23
+ **Problem**: The condition checks if the commit message starts with `release:` (lowercase with colon), but the merge commit was:
24
+ - Tag created: v1.7.7
25
+ - GitHub Release created
26
+ - NPM publish skipped (message started with "Release" not "release:")
27
+ - GitHub Packages publish skipped (same reason)
28
+
29
+ ## Solution Implemented
30
+
31
+ ### 1. Manual Publishing Workflow Created
32
+
33
+ Created `.github/workflows/manual-publish.yml` with:
34
+ - Manual trigger via GitHub Actions UI
35
+ - Checkboxes to select which registries to publish to:
36
+ - Publish to NPM Registry
37
+ - Publish to GitHub Packages
38
+ - Reads version from `library.properties` automatically
39
+ - Validates authentication tokens
40
+ - Provides clear success/failure feedback
41
+
42
+ ### 2. How to Use Manual Publishing
43
+
44
+ **Via GitHub UI:**
45
+ 1. Go to https://github.com/Alteriom/painlessMesh/actions
46
+ 2. Select "Manual Package Publishing" workflow
47
+ 3. Click "Run workflow" button
48
+ 4. Select desired options (both checked by default)
49
+ 5. Click "Run workflow"
50
+
51
+ **Via GitHub CLI:**
52
+ ```bash
53
+ gh workflow run manual-publish.yml
54
+ ```
55
+
56
+ ### 3. Documentation Updated
57
+
58
+ Updated `RELEASE_GUIDE.md` with:
59
+ - Explanation of the commit message requirement
60
+ - Troubleshooting section for this specific issue
61
+ - Instructions for using the manual publishing workflow
62
+ - Examples of correct vs incorrect commit messages
63
+
64
+ ## Immediate Action Required
65
+
66
+ To publish v1.7.7 to NPM and GitHub Packages:
67
+
68
+ 1. Navigate to: https://github.com/Alteriom/painlessMesh/actions/workflows/manual-publish.yml
69
+ 2. Click "Run workflow"
70
+ 3. Ensure both checkboxes are selected:
71
+ - Publish to NPM Registry
72
+ - Publish to GitHub Packages
73
+ 4. Click "Run workflow"
74
+
75
+ The workflow will:
76
+ - Read version 1.7.7 from library.properties
77
+ - Publish @alteriom/painlessmesh@1.7.7 to npmjs.org
78
+ - Publish to GitHub Packages registry
79
+
80
+ ## Prevention for Future Releases
81
+
82
+ To avoid this issue in future releases, ensure commit messages start with `release:` (lowercase with colon):
83
+
84
+ ** Correct:**
85
+ ```bash
86
+ git commit -m "release: v1.7.8 - Next version description"
87
+ ```
88
+
89
+ ** Wrong:**
90
+ ```bash
91
+ git commit -m "Release v1.7.8 - Next version description"
92
+ ```
93
+
94
+ ## Additional Notes
95
+
96
+ - The tag v1.7.7 exists and is correct
97
+ - GitHub Release exists and is correct
98
+ - Only NPM/GitHub Packages publishing needs to be done manually this time
99
+ - All other release channels (PlatformIO, Arduino Library Manager) are unaffected
100
+ - This is a one-time manual fix; future releases will work automatically if commit message is correct
101
+
102
+ ## Files Changed
103
+
104
+ 1. `.github/workflows/manual-publish.yml` - New manual publishing workflow
105
+ 2. `RELEASE_GUIDE.md` - Updated documentation with troubleshooting
106
+
107
+ ---
108
+
109
+ **Status**: Ready to manually publish v1.7.7 packages
110
+ **Action**: Run manual-publish.yml workflow via GitHub Actions UI
@@ -0,0 +1,172 @@
1
+ # Station Reconnection Issues in Bridge Mode
2
+
3
+ ## Problem Description
4
+
5
+ When using `stationManual()` to create a bridge node that connects to a router while also maintaining a mesh network, users may experience issues where the station (router) connection drops during mesh initialization and fails to reconnect automatically.
6
+
7
+ ### Symptoms
8
+
9
+ - Initial connection to router succeeds
10
+ - Mesh network initializes successfully
11
+ - Station connection drops with `ARDUINO_EVENT_WIFI_STA_DISCONNECTED` events
12
+ - Station never reconnects despite reconnection logic being triggered
13
+ - Serial output shows repeated disconnect events without successful reconnection
14
+
15
+ ### Example Serial Output
16
+
17
+ ```
18
+ === WiFi Connectivity Diagnostics ===
19
+ Step 1: Connecting to router to detect channel...
20
+ ✓ Successfully connected to router!
21
+ Router Channel: 6 ← Auto-detected!
22
+ Router IP: 192.168.18.11
23
+
24
+ Step 2: Initializing mesh on channel 6...
25
+ STARTUP: init(): 1
26
+ STARTUP: init(): Mesh channel set to 6
27
+ STARTUP: AP tcp server established on port 5555
28
+ STARTUP: stationManual(): Connecting to MyRouter
29
+ STARTUP: stationManual(): Connection initiated
30
+ ✓ Mesh initialized
31
+
32
+ Step 3: Waiting for station reconnection...
33
+ CONNECTION: eventSTADisconnectedHandler: ARDUINO_EVENT_WIFI_STA_DISCONNECTED
34
+ CONNECTION: eraseClosedConnections():
35
+ CONNECTION: eventSTADisconnectedHandler: ARDUINO_EVENT_WIFI_STA_DISCONNECTED
36
+ CONNECTION: eraseClosedConnections():
37
+ ⚠ Station not connected yet (may connect later)
38
+ ```
39
+
40
+ ## Root Cause
41
+
42
+ The issue was in the `connectToAP()` method in `src/painlessMeshSTA.cpp`. When operating in manual mode (for router connections via `stationManual()`):
43
+
44
+ 1. Station disconnects during mesh initialization (normal behavior in AP+STA mode)
45
+ 2. Disconnect callback triggers `yieldConnectToAP()` to reconnect
46
+ 3. `connectToAP()` checks if router SSID is in the scan results
47
+ 4. Router SSID is NOT in scan results (scan only looks for mesh nodes on mesh channel)
48
+ 5. Function returns without calling `WiFi.begin()` to reconnect
49
+ 6. Station remains disconnected indefinitely
50
+
51
+ ### Code Analysis
52
+
53
+ **Before Fix** (lines 192-195 in `painlessMeshSTA.cpp`):
54
+
55
+ ```cpp
56
+ } else if (aps.empty() || !ssid.equals(aps.begin()->ssid)) {
57
+ task.enableDelayed(SCAN_INTERVAL);
58
+ return; // ← Just delays, never attempts reconnection!
59
+ }
60
+ ```
61
+
62
+ The problem: This conditional assumes the router SSID will appear in the `aps` list from `stationScan()`. However, `stationScan()` only scans on the mesh channel for mesh nodes, not for routers which may be on the same or different channel.
63
+
64
+ ## Solution
65
+
66
+ **After Fix** (v1.8.1+):
67
+
68
+ ```cpp
69
+ } else {
70
+ // For manual router connections, reconnect directly using WiFi.begin()
71
+ // Don't rely on scan results since router may be on different channel
72
+ Log(CONNECTION,
73
+ "connectToAP(): Manual connection - attempting to reconnect to %s\n",
74
+ ssid.c_str());
75
+ WiFi.begin(ssid.c_str(), password.c_str());
76
+ task.enableDelayed(SCAN_INTERVAL);
77
+ return;
78
+ }
79
+ ```
80
+
81
+ The fix:
82
+ - Removes dependency on scan results for manual connections
83
+ - Calls `WiFi.begin()` directly to reconnect to the router
84
+ - Lets ESP hardware auto-detect the router's channel (as designed)
85
+ - Adds clear logging to show reconnection attempts
86
+
87
+ ## Verification
88
+
89
+ After applying the fix, the expected behavior is:
90
+
91
+ ```
92
+ Step 3: Waiting for station reconnection...
93
+ CONNECTION: eventSTADisconnectedHandler: ARDUINO_EVENT_WIFI_STA_DISCONNECTED
94
+ CONNECTION: eraseClosedConnections():
95
+ CONNECTION: connectToAP(): Manual connection - attempting to reconnect to MyRouter
96
+ ✓ Station reconnected successfully!
97
+ IP Address: 192.168.18.11
98
+ ```
99
+
100
+ ## Workaround (for older versions)
101
+
102
+ If you're using a version before v1.8.1, you can work around this issue by implementing explicit reconnection logic:
103
+
104
+ ```cpp
105
+ void setup() {
106
+ // ... mesh initialization ...
107
+
108
+ // Add a task to monitor and reconnect station
109
+ userScheduler.addTask(Task(5000, TASK_FOREVER, [](){
110
+ if (WiFi.status() != WL_CONNECTED) {
111
+ Serial.println("Station disconnected, reconnecting...");
112
+ WiFi.begin(ROUTER_SSID, ROUTER_PASSWORD);
113
+ }
114
+ }));
115
+ }
116
+ ```
117
+
118
+ ## Related Issues
119
+
120
+ - Issue #21: Original user report from @woodlist
121
+ - Issue #50: Bug tracking for stationManual() channel issues
122
+ - Issue #59: Bridge-centric architecture proposal
123
+ - PR #[number]: Fix implementation
124
+
125
+ ## Affected Versions
126
+
127
+ - **Affected**: v1.5.0 - v1.8.0
128
+ - **Fixed**: v1.8.1+
129
+
130
+ ## Platforms
131
+
132
+ This issue affects all ESP platforms:
133
+ - ESP32 (all variants including ESP32-C6, ESP32-S3)
134
+ - ESP8266
135
+
136
+ ## Additional Notes
137
+
138
+ ### Why Does Station Disconnect During Mesh Init?
139
+
140
+ When the ESP switches from pure STA mode to AP+STA mode during mesh initialization, the WiFi subsystem may briefly disconnect from the station to reconfigure. This is normal behavior and the library should automatically reconnect.
141
+
142
+ ### Channel Matching
143
+
144
+ Remember that in AP+STA mode, both the AP (mesh) and STA (router connection) **must use the same WiFi channel**. This is a hardware limitation. The fix ensures reconnection works regardless of channel, but both interfaces will still operate on the same channel.
145
+
146
+ ### Best Practice
147
+
148
+ For production bridge nodes, consider using the "Station First" pattern to auto-detect the router's channel before initializing the mesh:
149
+
150
+ ```cpp
151
+ void setup() {
152
+ // Step 1: Connect to router first to detect its channel
153
+ WiFi.mode(WIFI_STA);
154
+ WiFi.begin(ROUTER_SSID, ROUTER_PASSWORD);
155
+ while (WiFi.status() != WL_CONNECTED) {
156
+ delay(500);
157
+ }
158
+
159
+ uint8_t detectedChannel = WiFi.channel();
160
+ Serial.printf("Router channel: %d\n", detectedChannel);
161
+
162
+ WiFi.disconnect();
163
+ delay(1000);
164
+
165
+ // Step 2: Initialize mesh on the detected channel
166
+ mesh.init(MESH_SSID, MESH_PASSWORD, &userScheduler, MESH_PORT,
167
+ WIFI_AP_STA, detectedChannel);
168
+ mesh.stationManual(ROUTER_SSID, ROUTER_PASSWORD);
169
+ }
170
+ ```
171
+
172
+ This approach guarantees channel compatibility and more reliable connections.