diff --git a/CHANGELOG.md b/CHANGELOG.md index 4aecd2079..a6e3a3f4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ All notable changes to this project will be documented in this file. - ESP32 increase Serial Bridge input buffer from 130 to 520 characters ### Fixed +- ESP32 Arduino Core WiFi timeout is changed from msec to seconds +- Reduce blocking by adding WifiPollDns before resolving NTP and/or MQTT server names (#14394) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 702b3d74f..063d3aa33 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -142,6 +142,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - SCD40 start low power command [#15361](https://github.com/arendst/Tasmota/issues/15361) - BL09xx negative power presentation [#15374](https://github.com/arendst/Tasmota/issues/15374) - Possible pin output toggle after power on [#15630](https://github.com/arendst/Tasmota/issues/15630) +- Reduce blocking by adding WifiPollDns before resolving NTP and/or MQTT server names [#14394](https://github.com/arendst/Tasmota/issues/14394) +- ESP32 Arduino Core WiFi timeout is changed from msec to seconds ### Removed - Arduino IDE support diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index e9c119289..8ecdf570d 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -729,6 +729,30 @@ void wifiKeepAlive(void) { } #endif // ESP8266 +bool WifiPollDns(void) { + // WiFi.hostByName takes over ten seconds if no DNS server found + // This function checks to find the DNS server within 1 second + // This is an alternative for ping using less resources + WiFiClient DnsClient; + +#ifdef ESP8266 + DnsClient.setTimeout(1000); +#else + DnsClient.setTimeout(1); +#endif + uint32_t i = 3; // Check DNS1 only (to keep blocking to a minimum of 1 second) +// for (i = 3; i < 5; i++) { // Check DNS1 and DNS2 + uint32_t dns_address = (!TasmotaGlobal.global_state.eth_down) ? Settings->eth_ipv4_address[i] : Settings->ipv4_address[i]; + if (DnsClient.connect((IPAddress)dns_address, 53)) { + DnsClient.stop(); + return true; + } +// AddLog(LOG_LEVEL_DEBUG, PSTR("DNS: Disconnected %_I"), dns_address); + AddLog(LOG_LEVEL_DEBUG, PSTR("DNS: Disconnected")); +// } + return false; +} + void WifiPollNtp() { static uint8_t ntp_sync_minute = 0; static uint32_t ntp_run_time = 0; @@ -775,24 +799,26 @@ uint32_t WifiGetNtp(void) { char* ntp_server; bool resolved_ip = false; - for (uint32_t i = 0; i <= MAX_NTP_SERVERS; i++) { - if (ntp_server_id > 2) { ntp_server_id = 0; } - if (i < MAX_NTP_SERVERS) { - ntp_server = SettingsText(SET_NTPSERVER1 + ntp_server_id); - } else { - ntp_server = fallback_ntp_server; - } - if (strlen(ntp_server)) { - resolved_ip = (WiFi.hostByName(ntp_server, time_server_ip) == 1); // DNS timeout set to (ESP8266) 10s / (ESP32) 14s - if ((255 == time_server_ip[0]) || // No valid name resolved (255.255.255.255) - ((255 == time_server_ip[1]) && (255 == time_server_ip[2]) && (255 == time_server_ip[3]))) { // No valid name resolved (x.255.255.255) - resolved_ip = false; + if (WifiPollDns()) { + for (uint32_t i = 0; i <= MAX_NTP_SERVERS; i++) { + if (ntp_server_id > 2) { ntp_server_id = 0; } + if (i < MAX_NTP_SERVERS) { + ntp_server = SettingsText(SET_NTPSERVER1 + ntp_server_id); + } else { + ntp_server = fallback_ntp_server; } - yield(); - if (resolved_ip) { break; } -// AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve '%s'"), ntp_server); + if (strlen(ntp_server)) { + resolved_ip = (WiFi.hostByName(ntp_server, time_server_ip) == 1); // DNS timeout set to (ESP8266) 10s / (ESP32) 14s + if ((255 == time_server_ip[0]) || // No valid name resolved (255.255.255.255) + ((255 == time_server_ip[1]) && (255 == time_server_ip[2]) && (255 == time_server_ip[3]))) { // No valid name resolved (x.255.255.255) + resolved_ip = false; + } + yield(); + if (resolved_ip) { break; } + // AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve '%s'"), ntp_server); + } + ntp_server_id++; } - ntp_server_id++; } if (!resolved_ip) { AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve IP address")); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino index 5cec32eb6..5c474119f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino @@ -193,6 +193,17 @@ void MqttDisableLogging(bool state) { PubSubClient MqttClient; +void MqttSetClientTimeout(void) { +#ifdef ESP8266 + // setTimeout in msecs + EspClient.setTimeout(Settings->mqtt_wifi_timeout * 100); +#else + // setTimeout in secs + uint32_t timeout = (Settings->mqtt_wifi_timeout < 10) ? 1 : Settings->mqtt_wifi_timeout / 10; + EspClient.setTimeout(timeout); +#endif +} + void MqttInit(void) { // Force buffer size since the #define may not be visible from Arduino lib MqttClient.setBufferSize(MQTT_MAX_PACKET_SIZE); @@ -860,6 +871,20 @@ uint16_t MqttConnectCount(void) { } void MqttDisconnected(int state) { + /* + // Possible values for state - PubSubClient.h + Tasmota MQTT_DNS_DISCONNECTED -5 + #define MQTT_CONNECTION_TIMEOUT -4 + #define MQTT_CONNECTION_LOST -3 + #define MQTT_CONNECT_FAILED -2 + #define MQTT_DISCONNECTED -1 + #define MQTT_CONNECTED 0 + #define MQTT_CONNECT_BAD_PROTOCOL 1 + #define MQTT_CONNECT_BAD_CLIENT_ID 2 + #define MQTT_CONNECT_UNAVAILABLE 3 + #define MQTT_CONNECT_BAD_CREDENTIALS 4 + #define MQTT_CONNECT_UNAUTHORIZED 5 + */ Mqtt.connected = false; Mqtt.retry_counter = Settings->mqtt_retry * Mqtt.retry_counter_delay; @@ -1028,7 +1053,9 @@ void MqttReconnect(void) { Response_P(S_LWT_OFFLINE); if (MqttClient.connected()) { MqttClient.disconnect(); } - EspClient.setTimeout(Settings->mqtt_wifi_timeout * 100); + + MqttSetClientTimeout(); + #ifdef USE_MQTT_TLS if (Mqtt.mqtt_tls) { tlsClient->stop(); @@ -1056,6 +1083,11 @@ void MqttReconnect(void) { } } #endif + + if (!WifiPollDns()) { + MqttDisconnected(-5); // MQTT_DNS_DISCONNECTED + return; + } MqttClient.setServer(SettingsText(SET_MQTT_HOST), Settings->mqtt_port); uint32_t mqtt_connect_time = millis(); @@ -1363,7 +1395,7 @@ void CmndMqttWifiTimeout(void) { // Set timeout between 100 and 20000 mSec if ((XdrvMailbox.payload >= 100) && (XdrvMailbox.payload <= 20000)) { Settings->mqtt_wifi_timeout = XdrvMailbox.payload / 100; - EspClient.setTimeout(Settings->mqtt_wifi_timeout * 100); + MqttSetClientTimeout(); } ResponseCmndNumber(Settings->mqtt_wifi_timeout * 100); }