@alteriom/painlessmesh 1.9.17 → 1.9.19
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/CHANGELOG.md +31 -0
- package/README.md +1 -1
- package/examples/sendToInternet/README.md +29 -0
- package/library.json +1 -1
- package/library.properties +1 -1
- package/package.json +1 -1
- package/src/AlteriomPainlessMesh.h +2 -2
- package/src/arduino/wifi.hpp +64 -1
- package/src/painlessMesh.h +1 -1
- package/src/painlessmesh/mesh.hpp +31 -3
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
13
13
|
|
|
14
14
|
### Fixed
|
|
15
15
|
|
|
16
|
+
## [1.9.19] - 2025-12-21
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **Gateway Connectivity Error Non-Retryable Fix** - Infrastructure errors no longer waste time with futile retries
|
|
21
|
+
- Gateway connectivity errors ("Router has no internet", "Gateway WiFi not connected") are now non-retryable
|
|
22
|
+
- Distinguishes between infrastructure issues (need user fix) and transient errors (can retry)
|
|
23
|
+
- Provides immediate failure feedback instead of retrying for ~14+ seconds
|
|
24
|
+
- Saves battery and network resources by avoiding retries that can't succeed
|
|
25
|
+
- Clear error messages help users identify and fix infrastructure problems quickly
|
|
26
|
+
- Transient errors (HTTP 203, 5xx, 429, timeouts) still retry with exponential backoff
|
|
27
|
+
- New comprehensive test suite with 25 assertions covering retry logic
|
|
28
|
+
- Documentation: ISSUE_GATEWAY_CONNECTIVITY_NON_RETRYABLE_FIX.md
|
|
29
|
+
- Fully backward compatible: No API changes required
|
|
30
|
+
|
|
31
|
+
## [1.9.18] - 2025-12-21
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- **Internet Connectivity Check Enhancement** - Bridge nodes now verify actual internet access before processing HTTP requests
|
|
36
|
+
- Added `hasActualInternetAccess()` function that performs DNS resolution to detect router internet issues
|
|
37
|
+
- Gateway checks both WiFi association AND DNS resolution before attempting HTTP requests
|
|
38
|
+
- Provides early failure detection when router has no WAN connection
|
|
39
|
+
- Clear, actionable error messages help users troubleshoot connectivity problems:
|
|
40
|
+
- "Gateway WiFi not connected" - ESP not associated with WiFi network
|
|
41
|
+
- "Router has no internet access - check WAN connection" - WiFi OK but router offline
|
|
42
|
+
- Minimal performance impact: ~100ms DNS check vs 30+ second HTTP timeout
|
|
43
|
+
- New test suite with 22 assertions covering connectivity scenarios
|
|
44
|
+
- Documentation: ISSUE_INTERNET_CONNECTIVITY_CHECK.md
|
|
45
|
+
- Backward compatible: No API changes required
|
|
46
|
+
|
|
16
47
|
## [1.9.17] - 2025-12-21
|
|
17
48
|
|
|
18
49
|
### Changed
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
6
6
|
|
|
7
|
-
**Version 1.9.
|
|
7
|
+
**Version 1.9.19** - Gateway connectivity error non-retryable fix for infrastructure issues
|
|
8
8
|
|
|
9
9
|
[](https://github.com/Alteriom/painlessMesh/actions/workflows/ci.yml)
|
|
10
10
|
[](https://github.com/Alteriom/painlessMesh/actions/workflows/docs.yml)
|
|
@@ -146,6 +146,35 @@ mesh.sendToInternet("https://api.callmebot.com/...", "", callback);
|
|
|
146
146
|
3. Check HTTP status code in callback (200 = success)
|
|
147
147
|
4. URL-encode special characters in the message
|
|
148
148
|
|
|
149
|
+
### Gateway shows "no internet access" but WiFi is connected
|
|
150
|
+
|
|
151
|
+
**Symptom:** Error message "Router has no internet access - check WAN connection"
|
|
152
|
+
|
|
153
|
+
**Cause:** The gateway node is connected to WiFi but the router itself has no internet connectivity. This is detected through DNS resolution testing.
|
|
154
|
+
|
|
155
|
+
**Solutions:**
|
|
156
|
+
1. **Check router WAN connection:**
|
|
157
|
+
- Verify router's internet LED indicator
|
|
158
|
+
- Check router's WAN port cable connection
|
|
159
|
+
- Ensure modem is powered and connected
|
|
160
|
+
|
|
161
|
+
2. **Check ISP service:**
|
|
162
|
+
- Verify your internet service is active
|
|
163
|
+
- Test internet on other devices connected to same router
|
|
164
|
+
- Contact ISP if service is down
|
|
165
|
+
|
|
166
|
+
3. **Router configuration:**
|
|
167
|
+
- Verify router has obtained WAN IP address
|
|
168
|
+
- Check router's internet connection status page
|
|
169
|
+
- Restart router if necessary
|
|
170
|
+
|
|
171
|
+
**Technical Details:**
|
|
172
|
+
The gateway performs two connectivity checks:
|
|
173
|
+
1. `WiFi.status() == WL_CONNECTED` - Verifies WiFi association
|
|
174
|
+
2. DNS resolution test - Verifies actual internet routing
|
|
175
|
+
|
|
176
|
+
If WiFi is connected but DNS fails, it indicates the router has no upstream internet connection. This prevents unnecessary HTTP request timeouts and provides early error detection.
|
|
177
|
+
|
|
149
178
|
### Understanding HTTP Status Codes
|
|
150
179
|
|
|
151
180
|
The callback provides `httpStatus` to indicate the result:
|
package/library.json
CHANGED
package/library.properties
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name=Alteriom PainlessMesh
|
|
2
|
-
version=1.9.
|
|
2
|
+
version=1.9.19
|
|
3
3
|
author=Coopdis,Scotty Franzyshen,Edwin van Leeuwen,Germán Martín,Maximilian Schwarz,Doanh Doanh,Alteriom
|
|
4
4
|
maintainer=Alteriom
|
|
5
5
|
sentence=A painless way to setup a mesh with ESP8266 and ESP32 devices with Alteriom extensions
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alteriom/painlessmesh",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.19",
|
|
4
4
|
"description": "painlessMesh is a user-friendly library for creating mesh networks with ESP8266 and ESP32 devices. This Alteriom fork includes additional packages for sensor data (SensorPackage), device commands (CommandPackage), and status monitoring (StatusPackage). It handles routing and network management automatically, so you can focus on your application. The library uses JSON-based messaging and syncs time across all nodes, making it ideal for coordinated behaviour like synchronized light displays or sensor networks reporting to a central node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"arduino",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
/**
|
|
30
30
|
* @brief AlteriomPainlessMesh library version information
|
|
31
31
|
*/
|
|
32
|
-
#define ALTERIOM_PAINLESS_MESH_VERSION "1.9.
|
|
32
|
+
#define ALTERIOM_PAINLESS_MESH_VERSION "1.9.19"
|
|
33
33
|
#define ALTERIOM_PAINLESS_MESH_VERSION_MAJOR 1
|
|
34
34
|
#define ALTERIOM_PAINLESS_MESH_VERSION_MINOR 9
|
|
35
|
-
#define ALTERIOM_PAINLESS_MESH_VERSION_PATCH
|
|
35
|
+
#define ALTERIOM_PAINLESS_MESH_VERSION_PATCH 19
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* @brief Library description and usage information
|
package/src/arduino/wifi.hpp
CHANGED
|
@@ -2120,6 +2120,61 @@ class Mesh : public painlessmesh::Mesh<Connection> {
|
|
|
2120
2120
|
router::broadcast<protocol::Variant, Connection>(variant, (*this), 0);
|
|
2121
2121
|
}
|
|
2122
2122
|
|
|
2123
|
+
/**
|
|
2124
|
+
* Check if gateway has actual internet connectivity
|
|
2125
|
+
*
|
|
2126
|
+
* Tests DNS resolution to detect scenarios where WiFi is connected
|
|
2127
|
+
* but the router has no internet access. This provides early detection
|
|
2128
|
+
* before attempting HTTP requests that would timeout or fail.
|
|
2129
|
+
*
|
|
2130
|
+
* @return true if internet is accessible, false otherwise
|
|
2131
|
+
*/
|
|
2132
|
+
bool hasActualInternetAccess() {
|
|
2133
|
+
using namespace logger;
|
|
2134
|
+
|
|
2135
|
+
// First check WiFi connection
|
|
2136
|
+
if (WiFi.status() != WL_CONNECTED) {
|
|
2137
|
+
return false;
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
// Check if we have a valid local IP
|
|
2141
|
+
if (WiFi.localIP() == IPAddress(0, 0, 0, 0)) {
|
|
2142
|
+
return false;
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
// Try to resolve a well-known DNS name
|
|
2146
|
+
// Using Google's servers as they have high availability globally
|
|
2147
|
+
IPAddress result;
|
|
2148
|
+
|
|
2149
|
+
#if defined(ESP32) || defined(ESP8266)
|
|
2150
|
+
// Both ESP32 and ESP8266 support WiFi.hostByName()
|
|
2151
|
+
int dnsResult = WiFi.hostByName("www.google.com", result);
|
|
2152
|
+
|
|
2153
|
+
// Check if DNS resolution succeeded
|
|
2154
|
+
if (dnsResult != 1) {
|
|
2155
|
+
Log(COMMUNICATION, "hasActualInternetAccess(): DNS resolution failed (code=%d)\n", dnsResult);
|
|
2156
|
+
return false;
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2159
|
+
// Additional validation: Check if resolved IP is valid
|
|
2160
|
+
// Some ESP8266 versions may return success but set IP to 255.255.255.255 on error
|
|
2161
|
+
if (result == IPAddress(0, 0, 0, 0) || result == IPAddress(255, 255, 255, 255)) {
|
|
2162
|
+
TSTRING resultStr = result.toString();
|
|
2163
|
+
Log(COMMUNICATION, "hasActualInternetAccess(): Invalid DNS result IP: %s\n", resultStr.c_str());
|
|
2164
|
+
return false;
|
|
2165
|
+
}
|
|
2166
|
+
#else
|
|
2167
|
+
// Other platforms: assume internet is available if WiFi connected
|
|
2168
|
+
// (no reliable way to test without platform-specific APIs)
|
|
2169
|
+
return true;
|
|
2170
|
+
#endif
|
|
2171
|
+
|
|
2172
|
+
TSTRING resultStr = result.toString();
|
|
2173
|
+
Log(COMMUNICATION, "hasActualInternetAccess(): Internet connectivity verified (resolved to %s)\n",
|
|
2174
|
+
resultStr.c_str());
|
|
2175
|
+
return true;
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2123
2178
|
/**
|
|
2124
2179
|
* Helper method to send gateway acknowledgment
|
|
2125
2180
|
*/
|
|
@@ -2196,8 +2251,16 @@ class Mesh : public painlessmesh::Mesh<Connection> {
|
|
|
2196
2251
|
}
|
|
2197
2252
|
|
|
2198
2253
|
// Check Internet connectivity
|
|
2254
|
+
// First check WiFi status for quick fail
|
|
2199
2255
|
if (WiFi.status() != WL_CONNECTED) {
|
|
2200
|
-
sendGatewayAck(pkg, false, 0, "Gateway not connected
|
|
2256
|
+
sendGatewayAck(pkg, false, 0, "Gateway WiFi not connected");
|
|
2257
|
+
return true; // Consume package - we handled it (with error)
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
// Then check actual internet access (DNS resolution)
|
|
2261
|
+
// This detects when WiFi is connected but router has no internet
|
|
2262
|
+
if (!hasActualInternetAccess()) {
|
|
2263
|
+
sendGatewayAck(pkg, false, 0, "Router has no internet access - check WAN connection");
|
|
2201
2264
|
return true; // Consume package - we handled it (with error)
|
|
2202
2265
|
}
|
|
2203
2266
|
|
package/src/painlessMesh.h
CHANGED
|
@@ -1532,10 +1532,38 @@ class Mesh : public ntp::MeshTime, public plugin::PackageHandler<T> {
|
|
|
1532
1532
|
isRetryable = true;
|
|
1533
1533
|
Log(COMMUNICATION, "handleGatewayAck(): HTTP 429 rate limit, marking as retryable\n");
|
|
1534
1534
|
}
|
|
1535
|
-
// Network errors (httpStatus == 0)
|
|
1535
|
+
// Network errors (httpStatus == 0) EXCEPT gateway connectivity errors
|
|
1536
|
+
// Gateway connectivity errors are infrastructure issues (not transient)
|
|
1536
1537
|
else if (ack.httpStatus == 0) {
|
|
1537
|
-
|
|
1538
|
-
|
|
1538
|
+
// Check if this is a gateway-level connectivity error (non-retryable)
|
|
1539
|
+
bool isGatewayConnectivityError = false;
|
|
1540
|
+
|
|
1541
|
+
// These errors indicate infrastructure issues that won't be fixed by retrying:
|
|
1542
|
+
// - "Router has no internet access" - WAN connection down
|
|
1543
|
+
// - "Gateway WiFi not connected" - ESP not associated with WiFi
|
|
1544
|
+
// Use find() for std::string (test env) or indexOf() for Arduino String
|
|
1545
|
+
bool routerError = false, wifiError = false;
|
|
1546
|
+
#if defined(PAINLESSMESH_BOOST)
|
|
1547
|
+
// Test environment: TSTRING is std::string, use find()
|
|
1548
|
+
routerError = (ack.error.find("Router has no internet") != std::string::npos);
|
|
1549
|
+
wifiError = (ack.error.find("Gateway WiFi not connected") != std::string::npos);
|
|
1550
|
+
#else
|
|
1551
|
+
// Arduino environment: TSTRING is String, use indexOf()
|
|
1552
|
+
routerError = (ack.error.indexOf("Router has no internet") >= 0);
|
|
1553
|
+
wifiError = (ack.error.indexOf("Gateway WiFi not connected") >= 0);
|
|
1554
|
+
#endif
|
|
1555
|
+
|
|
1556
|
+
if (routerError || wifiError) {
|
|
1557
|
+
isGatewayConnectivityError = true;
|
|
1558
|
+
Log(COMMUNICATION, "handleGatewayAck(): Gateway connectivity error detected (non-retryable): %s\n",
|
|
1559
|
+
ack.error.c_str());
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
// Only mark as retryable if it's NOT a gateway connectivity error
|
|
1563
|
+
if (!isGatewayConnectivityError) {
|
|
1564
|
+
isRetryable = true;
|
|
1565
|
+
Log(COMMUNICATION, "handleGatewayAck(): Network error, marking as retryable\n");
|
|
1566
|
+
}
|
|
1539
1567
|
}
|
|
1540
1568
|
// HTTP 4xx client errors (except 429) are NOT retryable
|
|
1541
1569
|
// HTTP 3xx redirects are NOT retryable (should be followed by HTTPClient)
|