mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 09:01:49 +00:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			light-addr
			...
			2025.10.3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					6a478b9070 | ||
| 
						 | 
					a32a1d11fb | ||
| 
						 | 
					daeb8ef88c | ||
| 
						 | 
					febee437d6 | ||
| 
						 | 
					de2f475dbd | 
							
								
								
									
										2
									
								
								Doxyfile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Doxyfile
									
									
									
									
									
								
							@@ -48,7 +48,7 @@ PROJECT_NAME           = ESPHome
 | 
			
		||||
# could be handy for archiving the generated documentation or if some version
 | 
			
		||||
# control system is used.
 | 
			
		||||
 | 
			
		||||
PROJECT_NUMBER         = 2025.10.2
 | 
			
		||||
PROJECT_NUMBER         = 2025.10.3
 | 
			
		||||
 | 
			
		||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
 | 
			
		||||
# for a project that appears at the top of each page and should give viewer a
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,8 @@ void HDC1080Component::setup() {
 | 
			
		||||
 | 
			
		||||
  // if configuration fails - there is a problem
 | 
			
		||||
  if (this->write_register(HDC1080_CMD_CONFIGURATION, config, 2) != i2c::ERROR_OK) {
 | 
			
		||||
    this->mark_failed();
 | 
			
		||||
    ESP_LOGW(TAG, "Failed to configure HDC1080");
 | 
			
		||||
    this->status_set_warning();
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,13 @@ uint32_t ESP8266UartComponent::get_config() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESP8266UartComponent::setup() {
 | 
			
		||||
  if (this->rx_pin_) {
 | 
			
		||||
    this->rx_pin_->setup();
 | 
			
		||||
  }
 | 
			
		||||
  if (this->tx_pin_ && this->rx_pin_ != this->tx_pin_) {
 | 
			
		||||
    this->tx_pin_->setup();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Use Arduino HardwareSerial UARTs if all used pins match the ones
 | 
			
		||||
  // preconfigured by the platform. For example if RX disabled but TX pin
 | 
			
		||||
  // is 1 we still want to use Serial.
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,9 @@
 | 
			
		||||
#include "esphome/core/defines.h"
 | 
			
		||||
#include "esphome/core/helpers.h"
 | 
			
		||||
#include "esphome/core/log.h"
 | 
			
		||||
#include "esphome/core/gpio.h"
 | 
			
		||||
#include "driver/gpio.h"
 | 
			
		||||
#include "soc/gpio_num.h"
 | 
			
		||||
 | 
			
		||||
#ifdef USE_LOGGER
 | 
			
		||||
#include "esphome/components/logger/logger.h"
 | 
			
		||||
@@ -104,6 +107,13 @@ void IDFUARTComponent::load_settings(bool dump_config) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (this->rx_pin_) {
 | 
			
		||||
    this->rx_pin_->setup();
 | 
			
		||||
  }
 | 
			
		||||
  if (this->tx_pin_ && this->rx_pin_ != this->tx_pin_) {
 | 
			
		||||
    this->tx_pin_->setup();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int8_t tx = this->tx_pin_ != nullptr ? this->tx_pin_->get_pin() : -1;
 | 
			
		||||
  int8_t rx = this->rx_pin_ != nullptr ? this->rx_pin_->get_pin() : -1;
 | 
			
		||||
  int8_t flow_control = this->flow_control_pin_ != nullptr ? this->flow_control_pin_->get_pin() : -1;
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,13 @@ uint16_t LibreTinyUARTComponent::get_config() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LibreTinyUARTComponent::setup() {
 | 
			
		||||
  if (this->rx_pin_) {
 | 
			
		||||
    this->rx_pin_->setup();
 | 
			
		||||
  }
 | 
			
		||||
  if (this->tx_pin_ && this->rx_pin_ != this->tx_pin_) {
 | 
			
		||||
    this->tx_pin_->setup();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int8_t tx_pin = tx_pin_ == nullptr ? -1 : tx_pin_->get_pin();
 | 
			
		||||
  int8_t rx_pin = rx_pin_ == nullptr ? -1 : rx_pin_->get_pin();
 | 
			
		||||
  bool tx_inverted = tx_pin_ != nullptr && tx_pin_->is_inverted();
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,13 @@ uint16_t RP2040UartComponent::get_config() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RP2040UartComponent::setup() {
 | 
			
		||||
  if (this->rx_pin_) {
 | 
			
		||||
    this->rx_pin_->setup();
 | 
			
		||||
  }
 | 
			
		||||
  if (this->tx_pin_ && this->rx_pin_ != this->tx_pin_) {
 | 
			
		||||
    this->tx_pin_->setup();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uint16_t config = get_config();
 | 
			
		||||
 | 
			
		||||
  constexpr uint32_t valid_tx_uart_0 = __bitset({0, 12, 16, 28});
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ from enum import Enum
 | 
			
		||||
 | 
			
		||||
from esphome.enum import StrEnum
 | 
			
		||||
 | 
			
		||||
__version__ = "2025.10.2"
 | 
			
		||||
__version__ = "2025.10.3"
 | 
			
		||||
 | 
			
		||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
 | 
			
		||||
VALID_SUBSTITUTIONS_CHARACTERS = (
 | 
			
		||||
 
 | 
			
		||||
@@ -224,36 +224,37 @@ def resolve_ip_address(
 | 
			
		||||
        return res
 | 
			
		||||
 | 
			
		||||
    # Process hosts
 | 
			
		||||
    cached_addresses: list[str] = []
 | 
			
		||||
 | 
			
		||||
    uncached_hosts: list[str] = []
 | 
			
		||||
    has_cache = address_cache is not None
 | 
			
		||||
 | 
			
		||||
    for h in hosts:
 | 
			
		||||
        if is_ip_address(h):
 | 
			
		||||
            if has_cache:
 | 
			
		||||
                # If we have a cache, treat IPs as cached
 | 
			
		||||
                cached_addresses.append(h)
 | 
			
		||||
            else:
 | 
			
		||||
                # If no cache, pass IPs through to resolver with hostnames
 | 
			
		||||
                uncached_hosts.append(h)
 | 
			
		||||
            _add_ip_addresses_to_addrinfo([h], port, res)
 | 
			
		||||
        elif address_cache and (cached := address_cache.get_addresses(h)):
 | 
			
		||||
            # Found in cache
 | 
			
		||||
            cached_addresses.extend(cached)
 | 
			
		||||
            _add_ip_addresses_to_addrinfo(cached, port, res)
 | 
			
		||||
        else:
 | 
			
		||||
            # Not cached, need to resolve
 | 
			
		||||
            if address_cache and address_cache.has_cache():
 | 
			
		||||
                _LOGGER.info("Host %s not in cache, will need to resolve", h)
 | 
			
		||||
            uncached_hosts.append(h)
 | 
			
		||||
 | 
			
		||||
    # Process cached addresses (includes direct IPs and cached lookups)
 | 
			
		||||
    _add_ip_addresses_to_addrinfo(cached_addresses, port, res)
 | 
			
		||||
 | 
			
		||||
    # If we have uncached hosts (only non-IP hostnames), resolve them
 | 
			
		||||
    if uncached_hosts:
 | 
			
		||||
        from aioesphomeapi.host_resolver import AddrInfo as AioAddrInfo
 | 
			
		||||
 | 
			
		||||
        from esphome.core import EsphomeError
 | 
			
		||||
        from esphome.resolver import AsyncResolver
 | 
			
		||||
 | 
			
		||||
        resolver = AsyncResolver(uncached_hosts, port)
 | 
			
		||||
        addr_infos: list[AioAddrInfo] = []
 | 
			
		||||
        try:
 | 
			
		||||
            addr_infos = resolver.resolve()
 | 
			
		||||
        except EsphomeError as err:
 | 
			
		||||
            if not res:
 | 
			
		||||
                # No pre-resolved addresses available, DNS resolution is fatal
 | 
			
		||||
                raise
 | 
			
		||||
            _LOGGER.info("%s (using %d already resolved IP addresses)", err, len(res))
 | 
			
		||||
 | 
			
		||||
        # Convert aioesphomeapi AddrInfo to our format
 | 
			
		||||
        for addr_info in addr_infos:
 | 
			
		||||
            sockaddr = addr_info.sockaddr
 | 
			
		||||
 
 | 
			
		||||
@@ -454,9 +454,27 @@ def test_resolve_ip_address_mixed_list() -> None:
 | 
			
		||||
        # Mix of IP and hostname - should use async resolver
 | 
			
		||||
        result = helpers.resolve_ip_address(["192.168.1.100", "test.local"], 6053)
 | 
			
		||||
 | 
			
		||||
        assert len(result) == 2
 | 
			
		||||
        assert result[0][4][0] == "192.168.1.100"
 | 
			
		||||
        assert result[1][4][0] == "192.168.1.200"
 | 
			
		||||
        MockResolver.assert_called_once_with(["test.local"], 6053)
 | 
			
		||||
        mock_resolver.resolve.assert_called_once()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_resolve_ip_address_mixed_list_fail() -> None:
 | 
			
		||||
    """Test resolving a mix of IPs and hostnames with resolve failed."""
 | 
			
		||||
    with patch("esphome.resolver.AsyncResolver") as MockResolver:
 | 
			
		||||
        mock_resolver = MockResolver.return_value
 | 
			
		||||
        mock_resolver.resolve.side_effect = EsphomeError(
 | 
			
		||||
            "Error resolving IP address: [test.local]"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        # Mix of IP and hostname - should use async resolver
 | 
			
		||||
        result = helpers.resolve_ip_address(["192.168.1.100", "test.local"], 6053)
 | 
			
		||||
 | 
			
		||||
        assert len(result) == 1
 | 
			
		||||
        assert result[0][4][0] == "192.168.1.200"
 | 
			
		||||
        MockResolver.assert_called_once_with(["192.168.1.100", "test.local"], 6053)
 | 
			
		||||
        assert result[0][4][0] == "192.168.1.100"
 | 
			
		||||
        MockResolver.assert_called_once_with(["test.local"], 6053)
 | 
			
		||||
        mock_resolver.resolve.assert_called_once()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user