From 9b78098eec3c965df24933d2230885381997b399 Mon Sep 17 00:00:00 2001 From: optimusprimespace <62800678+optimusprimespace@users.noreply.github.com> Date: Thu, 23 Oct 2025 05:24:17 +0300 Subject: [PATCH 1/9] [hdc2010] New component (#6674) Co-authored-by: Keith Burzinski Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> --- CODEOWNERS | 1 + esphome/components/hdc2010/__init__.py | 1 + esphome/components/hdc2010/hdc2010.cpp | 111 ++++++++++++++++++ esphome/components/hdc2010/hdc2010.h | 32 +++++ esphome/components/hdc2010/sensor.py | 56 +++++++++ tests/components/hdc2010/common.yaml | 7 ++ .../components/hdc2010/test.esp32-c3-idf.yaml | 4 + tests/components/hdc2010/test.esp32-idf.yaml | 4 + .../components/hdc2010/test.esp8266-ard.yaml | 4 + tests/components/hdc2010/test.rp2040-ard.yaml | 4 + 10 files changed, 224 insertions(+) create mode 100644 esphome/components/hdc2010/__init__.py create mode 100644 esphome/components/hdc2010/hdc2010.cpp create mode 100644 esphome/components/hdc2010/hdc2010.h create mode 100644 esphome/components/hdc2010/sensor.py create mode 100644 tests/components/hdc2010/common.yaml create mode 100644 tests/components/hdc2010/test.esp32-c3-idf.yaml create mode 100644 tests/components/hdc2010/test.esp32-idf.yaml create mode 100644 tests/components/hdc2010/test.esp8266-ard.yaml create mode 100644 tests/components/hdc2010/test.rp2040-ard.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 4f860375d9..667a44fc03 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -201,6 +201,7 @@ esphome/components/havells_solar/* @sourabhjaiswal esphome/components/hbridge/fan/* @WeekendWarrior esphome/components/hbridge/light/* @DotNetDann esphome/components/hbridge/switch/* @dwmw2 +esphome/components/hdc2010/* @optimusprimespace @ssieb esphome/components/he60r/* @clydebarrow esphome/components/heatpumpir/* @rob-deutsch esphome/components/hitachi_ac424/* @sourabhjaiswal diff --git a/esphome/components/hdc2010/__init__.py b/esphome/components/hdc2010/__init__.py new file mode 100644 index 0000000000..badf9dbb0c --- /dev/null +++ b/esphome/components/hdc2010/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@optimusprimespace", "@ssieb"] diff --git a/esphome/components/hdc2010/hdc2010.cpp b/esphome/components/hdc2010/hdc2010.cpp new file mode 100644 index 0000000000..c53fdb3f5b --- /dev/null +++ b/esphome/components/hdc2010/hdc2010.cpp @@ -0,0 +1,111 @@ +#include "esphome/core/hal.h" +#include "hdc2010.h" +// https://github.com/vigsterkr/homebridge-hdc2010/blob/main/src/hdc2010.js +// https://github.com/lime-labs/HDC2080-Arduino/blob/master/src/HDC2080.cpp +namespace esphome { +namespace hdc2010 { + +static const char *const TAG = "hdc2010"; + +static const uint8_t HDC2010_ADDRESS = 0x40; // 0b1000000 or 0b1000001 from datasheet +static const uint8_t HDC2010_CMD_CONFIGURATION_MEASUREMENT = 0x8F; +static const uint8_t HDC2010_CMD_START_MEASUREMENT = 0xF9; +static const uint8_t HDC2010_CMD_TEMPERATURE_LOW = 0x00; +static const uint8_t HDC2010_CMD_TEMPERATURE_HIGH = 0x01; +static const uint8_t HDC2010_CMD_HUMIDITY_LOW = 0x02; +static const uint8_t HDC2010_CMD_HUMIDITY_HIGH = 0x03; +static const uint8_t CONFIG = 0x0E; +static const uint8_t MEASUREMENT_CONFIG = 0x0F; + +void HDC2010Component::setup() { + ESP_LOGCONFIG(TAG, "Running setup"); + + const uint8_t data[2] = { + 0b00000000, // resolution 14bit for both humidity and temperature + 0b00000000 // reserved + }; + + if (!this->write_bytes(HDC2010_CMD_CONFIGURATION_MEASUREMENT, data, 2)) { + ESP_LOGW(TAG, "Initial config instruction error"); + this->status_set_warning(); + return; + } + + // Set measurement mode to temperature and humidity + uint8_t config_contents; + this->read_register(MEASUREMENT_CONFIG, &config_contents, 1); + config_contents = (config_contents & 0xF9); // Always set to TEMP_AND_HUMID mode + this->write_bytes(MEASUREMENT_CONFIG, &config_contents, 1); + + // Set rate to manual + this->read_register(CONFIG, &config_contents, 1); + config_contents &= 0x8F; + this->write_bytes(CONFIG, &config_contents, 1); + + // Set temperature resolution to 14bit + this->read_register(CONFIG, &config_contents, 1); + config_contents &= 0x3F; + this->write_bytes(CONFIG, &config_contents, 1); + + // Set humidity resolution to 14bit + this->read_register(CONFIG, &config_contents, 1); + config_contents &= 0xCF; + this->write_bytes(CONFIG, &config_contents, 1); +} + +void HDC2010Component::dump_config() { + ESP_LOGCONFIG(TAG, "HDC2010:"); + LOG_I2C_DEVICE(this); + if (this->is_failed()) { + ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL); + } + LOG_UPDATE_INTERVAL(this); + LOG_SENSOR(" ", "Temperature", this->temperature_sensor_); + LOG_SENSOR(" ", "Humidity", this->humidity_sensor_); +} + +void HDC2010Component::update() { + // Trigger measurement + uint8_t config_contents; + this->read_register(CONFIG, &config_contents, 1); + config_contents |= 0x01; + this->write_bytes(MEASUREMENT_CONFIG, &config_contents, 1); + + // 1ms delay after triggering the sample + set_timeout(1, [this]() { + if (this->temperature_sensor_ != nullptr) { + float temp = this->read_temp(); + this->temperature_sensor_->publish_state(temp); + ESP_LOGD(TAG, "Temp=%.1f°C", temp); + } + + if (this->humidity_sensor_ != nullptr) { + float humidity = this->read_humidity(); + this->humidity_sensor_->publish_state(humidity); + ESP_LOGD(TAG, "Humidity=%.1f%%", humidity); + } + }); +} + +float HDC2010Component::read_temp() { + uint8_t byte[2]; + + this->read_register(HDC2010_CMD_TEMPERATURE_LOW, &byte[0], 1); + this->read_register(HDC2010_CMD_TEMPERATURE_HIGH, &byte[1], 1); + + uint16_t temp = encode_uint16(byte[1], byte[0]); + return (float) temp * 0.0025177f - 40.0f; +} + +float HDC2010Component::read_humidity() { + uint8_t byte[2]; + + this->read_register(HDC2010_CMD_HUMIDITY_LOW, &byte[0], 1); + this->read_register(HDC2010_CMD_HUMIDITY_HIGH, &byte[1], 1); + + uint16_t humidity = encode_uint16(byte[1], byte[0]); + return (float) humidity * 0.001525879f; +} + +} // namespace hdc2010 +} // namespace esphome diff --git a/esphome/components/hdc2010/hdc2010.h b/esphome/components/hdc2010/hdc2010.h new file mode 100644 index 0000000000..52c00686e6 --- /dev/null +++ b/esphome/components/hdc2010/hdc2010.h @@ -0,0 +1,32 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/components/i2c/i2c.h" + +namespace esphome { +namespace hdc2010 { + +class HDC2010Component : public PollingComponent, public i2c::I2CDevice { + public: + void set_temperature_sensor(sensor::Sensor *temperature) { this->temperature_sensor_ = temperature; } + + void set_humidity_sensor(sensor::Sensor *humidity) { this->humidity_sensor_ = humidity; } + + /// Setup the sensor and check for connection. + void setup() override; + void dump_config() override; + /// Retrieve the latest sensor values. This operation takes approximately 16ms. + void update() override; + + float read_temp(); + + float read_humidity(); + + protected: + sensor::Sensor *temperature_sensor_{nullptr}; + sensor::Sensor *humidity_sensor_{nullptr}; +}; + +} // namespace hdc2010 +} // namespace esphome diff --git a/esphome/components/hdc2010/sensor.py b/esphome/components/hdc2010/sensor.py new file mode 100644 index 0000000000..15e19f2cc8 --- /dev/null +++ b/esphome/components/hdc2010/sensor.py @@ -0,0 +1,56 @@ +import esphome.codegen as cg +from esphome.components import i2c, sensor +import esphome.config_validation as cv +from esphome.const import ( + CONF_HUMIDITY, + CONF_ID, + CONF_TEMPERATURE, + DEVICE_CLASS_HUMIDITY, + DEVICE_CLASS_TEMPERATURE, + STATE_CLASS_MEASUREMENT, + UNIT_CELSIUS, + UNIT_PERCENT, +) + +DEPENDENCIES = ["i2c"] + +hdc2010_ns = cg.esphome_ns.namespace("hdc2010") +HDC2010Component = hdc2010_ns.class_( + "HDC2010Component", cg.PollingComponent, i2c.I2CDevice +) + +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(HDC2010Component), + cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( + unit_of_measurement=UNIT_CELSIUS, + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_HUMIDITY): sensor.sensor_schema( + unit_of_measurement=UNIT_PERCENT, + accuracy_decimals=0, + device_class=DEVICE_CLASS_HUMIDITY, + state_class=STATE_CLASS_MEASUREMENT, + ), + } + ) + .extend(cv.polling_component_schema("60s")) + .extend(i2c.i2c_device_schema(0x40)) +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await i2c.register_i2c_device(var, config) + + if temperature_config := config.get(CONF_TEMPERATURE): + sens = await sensor.new_sensor(temperature_config) + cg.add(var.set_temperature_sensor(sens)) + + if humidity_config := config.get(CONF_HUMIDITY): + sens = await sensor.new_sensor(humidity_config) + cg.add(var.set_humidity_sensor(sens)) diff --git a/tests/components/hdc2010/common.yaml b/tests/components/hdc2010/common.yaml new file mode 100644 index 0000000000..a22b3f15ce --- /dev/null +++ b/tests/components/hdc2010/common.yaml @@ -0,0 +1,7 @@ +sensor: + - platform: hdc2010 + i2c_id: i2c_bus + temperature: + name: Temperature + humidity: + name: Humidity diff --git a/tests/components/hdc2010/test.esp32-c3-idf.yaml b/tests/components/hdc2010/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..9990d96d29 --- /dev/null +++ b/tests/components/hdc2010/test.esp32-c3-idf.yaml @@ -0,0 +1,4 @@ +packages: + i2c: !include ../../test_build_components/common/i2c/esp32-c3-idf.yaml + +<<: !include common.yaml diff --git a/tests/components/hdc2010/test.esp32-idf.yaml b/tests/components/hdc2010/test.esp32-idf.yaml new file mode 100644 index 0000000000..b47e39c389 --- /dev/null +++ b/tests/components/hdc2010/test.esp32-idf.yaml @@ -0,0 +1,4 @@ +packages: + i2c: !include ../../test_build_components/common/i2c/esp32-idf.yaml + +<<: !include common.yaml diff --git a/tests/components/hdc2010/test.esp8266-ard.yaml b/tests/components/hdc2010/test.esp8266-ard.yaml new file mode 100644 index 0000000000..4a98b9388a --- /dev/null +++ b/tests/components/hdc2010/test.esp8266-ard.yaml @@ -0,0 +1,4 @@ +packages: + i2c: !include ../../test_build_components/common/i2c/esp8266-ard.yaml + +<<: !include common.yaml diff --git a/tests/components/hdc2010/test.rp2040-ard.yaml b/tests/components/hdc2010/test.rp2040-ard.yaml new file mode 100644 index 0000000000..319a7c71a6 --- /dev/null +++ b/tests/components/hdc2010/test.rp2040-ard.yaml @@ -0,0 +1,4 @@ +packages: + i2c: !include ../../test_build_components/common/i2c/rp2040-ard.yaml + +<<: !include common.yaml From d23e25f0991cb20900c0de5576218c3623d7a59e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 22 Oct 2025 16:31:51 -1000 Subject: [PATCH 2/9] [api] Fix clang-tidy modernize-use-emplace warning for light effects (#11490) --- esphome/components/api/api_connection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 7c135946f8..f76080253d 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -486,7 +486,7 @@ uint16_t APIConnection::try_send_light_info(EntityBase *entity, APIConnection *c if (light->supports_effects()) { msg.effects.emplace_back("None"); for (auto *effect : light->get_effects()) { - msg.effects.push_back(effect->get_name()); + msg.effects.emplace_back(effect->get_name()); } } return fill_and_encode_entity_info(light, msg, ListEntitiesLightResponse::MESSAGE_TYPE, conn, remaining_size, From 6c2ce5cacff9bf151642ee8c2185349de697c420 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:36:30 -1000 Subject: [PATCH 3/9] Bump bleak from 1.0.1 to 1.1.1 (#11492) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6966ebe583..59592ec0a2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ pillow==11.3.0 cairosvg==2.8.2 freetype-py==2.5.1 jinja2==3.1.6 -bleak==1.0.1 +bleak==1.1.1 # esp-idf >= 5.0 requires this pyparsing >= 3.0 From 5b023f9369e3ce84e4f8b5717928bd9bbc1e735c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 22 Oct 2025 16:37:50 -1000 Subject: [PATCH 4/9] [ethernet] Add RMII GPIO pin conflict validation (#11488) --- esphome/components/ethernet/__init__.py | 84 ++++++++++++++++++- tests/components/ethernet/common-dp83848.yaml | 4 +- tests/components/ethernet/common-ip101.yaml | 4 +- tests/components/ethernet/common-jl1101.yaml | 4 +- tests/components/ethernet/common-ksz8081.yaml | 4 +- .../ethernet/common-ksz8081rna.yaml | 4 +- tests/components/ethernet/common-lan8670.yaml | 4 +- tests/components/ethernet/common-lan8720.yaml | 4 +- tests/components/ethernet/common-rtl8201.yaml | 4 +- tests/components/ethernet_info/common.yaml | 4 +- 10 files changed, 98 insertions(+), 22 deletions(-) diff --git a/esphome/components/ethernet/__init__.py b/esphome/components/ethernet/__init__.py index 7384bb26d3..77f70a3630 100644 --- a/esphome/components/ethernet/__init__.py +++ b/esphome/components/ethernet/__init__.py @@ -32,6 +32,7 @@ from esphome.const import ( CONF_MISO_PIN, CONF_MODE, CONF_MOSI_PIN, + CONF_NUMBER, CONF_PAGE_ID, CONF_PIN, CONF_POLLING_INTERVAL, @@ -52,12 +53,36 @@ from esphome.core import ( coroutine_with_priority, ) import esphome.final_validate as fv +from esphome.types import ConfigType CONFLICTS_WITH = ["wifi"] DEPENDENCIES = ["esp32"] AUTO_LOAD = ["network"] LOGGER = logging.getLogger(__name__) +# RMII pins that are hardcoded on ESP32 classic and cannot be changed +# These pins are used by the internal Ethernet MAC when using RMII PHYs +ESP32_RMII_FIXED_PINS = { + 19: "EMAC_TXD0", + 21: "EMAC_TX_EN", + 22: "EMAC_TXD1", + 25: "EMAC_RXD0", + 26: "EMAC_RXD1", + 27: "EMAC_RX_CRS_DV", +} + +# RMII default pins for ESP32-P4 +# These are the default pins used by ESP-IDF and are configurable in principle, +# but ESPHome's ethernet component currently has no way to change them +ESP32P4_RMII_DEFAULT_PINS = { + 34: "EMAC_TXD0", + 35: "EMAC_TXD1", + 28: "EMAC_RX_CRS_DV", + 29: "EMAC_RXD0", + 30: "EMAC_RXD1", + 49: "EMAC_TX_EN", +} + ethernet_ns = cg.esphome_ns.namespace("ethernet") PHYRegister = ethernet_ns.struct("PHYRegister") CONF_PHY_ADDR = "phy_addr" @@ -273,7 +298,7 @@ CONFIG_SCHEMA = cv.All( ) -def _final_validate(config): +def _final_validate_spi(config): if config[CONF_TYPE] not in SPI_ETHERNET_TYPES: return if spi_configs := fv.full_config.get().get(CONF_SPI): @@ -292,9 +317,6 @@ def _final_validate(config): ) -FINAL_VALIDATE_SCHEMA = _final_validate - - def manual_ip(config): return cg.StructInitializer( ManualIP, @@ -383,3 +405,57 @@ async def to_code(config): if CORE.using_arduino: cg.add_library("WiFi", None) + + +def _final_validate_rmii_pins(config: ConfigType) -> None: + """Validate that RMII pins are not used by other components.""" + # Only validate for RMII-based PHYs on ESP32/ESP32P4 + if config[CONF_TYPE] in SPI_ETHERNET_TYPES or config[CONF_TYPE] == "OPENETH": + return # SPI and OPENETH don't use RMII + + variant = get_esp32_variant() + if variant == VARIANT_ESP32: + rmii_pins = ESP32_RMII_FIXED_PINS + is_configurable = False + elif variant == VARIANT_ESP32P4: + rmii_pins = ESP32P4_RMII_DEFAULT_PINS + is_configurable = True + else: + return # No RMII validation needed for other variants + + # Check all used pins against RMII reserved pins + for pin_list in pins.PIN_SCHEMA_REGISTRY.pins_used.values(): + for pin_path, _, pin_config in pin_list: + pin_num = pin_config.get(CONF_NUMBER) + if pin_num not in rmii_pins: + continue + # Found a conflict - show helpful error message + pin_function = rmii_pins[pin_num] + component_path = ".".join(str(p) for p in pin_path) + if is_configurable: + error_msg = ( + f"GPIO{pin_num} is used by Ethernet RMII " + f"({pin_function}) with the current default " + f"configuration. This conflicts with '{component_path}'. " + f"Please choose a different GPIO pin for " + f"'{component_path}'." + ) + else: + error_msg = ( + f"GPIO{pin_num} is reserved for Ethernet RMII " + f"({pin_function}) and cannot be used. This pin is " + f"hardcoded by ESP-IDF and cannot be changed when using " + f"RMII Ethernet PHYs. Please choose a different GPIO pin " + f"for '{component_path}'." + ) + raise cv.Invalid(error_msg, path=pin_path) + + +def _final_validate(config: ConfigType) -> ConfigType: + """Final validation for Ethernet component.""" + _final_validate_spi(config) + _final_validate_rmii_pins(config) + return config + + +FINAL_VALIDATE_SCHEMA = _final_validate diff --git a/tests/components/ethernet/common-dp83848.yaml b/tests/components/ethernet/common-dp83848.yaml index 7cedfeaf08..f9069c5fb9 100644 --- a/tests/components/ethernet/common-dp83848.yaml +++ b/tests/components/ethernet/common-dp83848.yaml @@ -1,12 +1,12 @@ ethernet: type: DP83848 mdc_pin: 23 - mdio_pin: 25 + mdio_pin: 32 clk: pin: 0 mode: CLK_EXT_IN phy_addr: 0 - power_pin: 26 + power_pin: 33 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1 diff --git a/tests/components/ethernet/common-ip101.yaml b/tests/components/ethernet/common-ip101.yaml index 2dece15171..cea7a5cc35 100644 --- a/tests/components/ethernet/common-ip101.yaml +++ b/tests/components/ethernet/common-ip101.yaml @@ -1,12 +1,12 @@ ethernet: type: IP101 mdc_pin: 23 - mdio_pin: 25 + mdio_pin: 32 clk: pin: 0 mode: CLK_EXT_IN phy_addr: 0 - power_pin: 26 + power_pin: 33 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1 diff --git a/tests/components/ethernet/common-jl1101.yaml b/tests/components/ethernet/common-jl1101.yaml index b6ea884102..7b0a2dfdc4 100644 --- a/tests/components/ethernet/common-jl1101.yaml +++ b/tests/components/ethernet/common-jl1101.yaml @@ -1,12 +1,12 @@ ethernet: type: JL1101 mdc_pin: 23 - mdio_pin: 25 + mdio_pin: 32 clk: pin: 0 mode: CLK_EXT_IN phy_addr: 0 - power_pin: 26 + power_pin: 33 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1 diff --git a/tests/components/ethernet/common-ksz8081.yaml b/tests/components/ethernet/common-ksz8081.yaml index f70d42319e..65541832c2 100644 --- a/tests/components/ethernet/common-ksz8081.yaml +++ b/tests/components/ethernet/common-ksz8081.yaml @@ -1,12 +1,12 @@ ethernet: type: KSZ8081 mdc_pin: 23 - mdio_pin: 25 + mdio_pin: 32 clk: pin: 0 mode: CLK_EXT_IN phy_addr: 0 - power_pin: 26 + power_pin: 33 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1 diff --git a/tests/components/ethernet/common-ksz8081rna.yaml b/tests/components/ethernet/common-ksz8081rna.yaml index 18efdae0e1..f04cba15b2 100644 --- a/tests/components/ethernet/common-ksz8081rna.yaml +++ b/tests/components/ethernet/common-ksz8081rna.yaml @@ -1,12 +1,12 @@ ethernet: type: KSZ8081RNA mdc_pin: 23 - mdio_pin: 25 + mdio_pin: 32 clk: pin: 0 mode: CLK_EXT_IN phy_addr: 0 - power_pin: 26 + power_pin: 33 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1 diff --git a/tests/components/ethernet/common-lan8670.yaml b/tests/components/ethernet/common-lan8670.yaml index ec2f24273d..fb751ebd23 100644 --- a/tests/components/ethernet/common-lan8670.yaml +++ b/tests/components/ethernet/common-lan8670.yaml @@ -1,12 +1,12 @@ ethernet: type: LAN8670 mdc_pin: 23 - mdio_pin: 25 + mdio_pin: 32 clk: pin: 0 mode: CLK_EXT_IN phy_addr: 0 - power_pin: 26 + power_pin: 33 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1 diff --git a/tests/components/ethernet/common-lan8720.yaml b/tests/components/ethernet/common-lan8720.yaml index 204c1d9210..838d57df28 100644 --- a/tests/components/ethernet/common-lan8720.yaml +++ b/tests/components/ethernet/common-lan8720.yaml @@ -1,12 +1,12 @@ ethernet: type: LAN8720 mdc_pin: 23 - mdio_pin: 25 + mdio_pin: 32 clk: pin: 0 mode: CLK_EXT_IN phy_addr: 0 - power_pin: 26 + power_pin: 33 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1 diff --git a/tests/components/ethernet/common-rtl8201.yaml b/tests/components/ethernet/common-rtl8201.yaml index 8b9f2b86f2..0e7cbe73c6 100644 --- a/tests/components/ethernet/common-rtl8201.yaml +++ b/tests/components/ethernet/common-rtl8201.yaml @@ -1,12 +1,12 @@ ethernet: type: RTL8201 mdc_pin: 23 - mdio_pin: 25 + mdio_pin: 32 clk: pin: 0 mode: CLK_EXT_IN phy_addr: 0 - power_pin: 26 + power_pin: 33 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1 diff --git a/tests/components/ethernet_info/common.yaml b/tests/components/ethernet_info/common.yaml index f45f345316..b720521d10 100644 --- a/tests/components/ethernet_info/common.yaml +++ b/tests/components/ethernet_info/common.yaml @@ -1,12 +1,12 @@ ethernet: type: LAN8720 mdc_pin: 23 - mdio_pin: 25 + mdio_pin: 32 clk: pin: 0 mode: CLK_EXT_IN phy_addr: 0 - power_pin: 26 + power_pin: 33 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1 From 3d21adecd335e683b695ccfc00175da442214893 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 02:58:09 +0000 Subject: [PATCH 5/9] Bump aioesphomeapi from 42.2.0 to 42.3.0 (#11493) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 59592ec0a2..351143591a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20251013.0 -aioesphomeapi==42.2.0 +aioesphomeapi==42.3.0 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.18.15 # dashboard_import From 917deac7cb7d6747f06a3c9546be85b3433e29b5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 22 Oct 2025 18:02:19 -1000 Subject: [PATCH 6/9] [scheduler] Remove unused include after defer queue optimization (#11491) --- esphome/core/scheduler.h | 1 - 1 file changed, 1 deletion(-) diff --git a/esphome/core/scheduler.h b/esphome/core/scheduler.h index ad0ec0284e..df0be0e4ce 100644 --- a/esphome/core/scheduler.h +++ b/esphome/core/scheduler.h @@ -4,7 +4,6 @@ #include #include #include -#include #ifdef ESPHOME_THREAD_MULTI_ATOMICS #include #endif From f9b08491cc54d8fe24f3f5ce1a25ee257f5d0d09 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 23 Oct 2025 06:50:24 -0600 Subject: [PATCH 7/9] [tests] Fix millis() ambiguity in component tests with gps component --- tests/components/absolute_humidity/common.yaml | 4 ++-- tests/components/analog_threshold/common.yaml | 2 +- tests/components/bang_bang/common.yaml | 2 +- tests/components/binary_sensor_map/common.yaml | 6 +++--- tests/components/combination/common.yaml | 4 ++-- tests/components/duty_time/common.yaml | 2 +- tests/components/endstop/common.yaml | 2 +- tests/components/lock/common.yaml | 2 +- tests/components/pid/common.yaml | 2 +- tests/components/prometheus/common.yaml | 12 ++++++------ 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/components/absolute_humidity/common.yaml b/tests/components/absolute_humidity/common.yaml index 026f88654f..f6b1c02886 100644 --- a/tests/components/absolute_humidity/common.yaml +++ b/tests/components/absolute_humidity/common.yaml @@ -6,14 +6,14 @@ sensor: - platform: template id: template_humidity lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return 0.6; } return 0.0; - platform: template id: template_temperature lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return 42.0; } return 0.0; diff --git a/tests/components/analog_threshold/common.yaml b/tests/components/analog_threshold/common.yaml index 26c401b92a..7d9dc4bc9b 100644 --- a/tests/components/analog_threshold/common.yaml +++ b/tests/components/analog_threshold/common.yaml @@ -3,7 +3,7 @@ sensor: id: template_sensor name: Template Sensor lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return 42.0; } return 0.0; diff --git a/tests/components/bang_bang/common.yaml b/tests/components/bang_bang/common.yaml index 5882025191..dc7798e2f2 100644 --- a/tests/components/bang_bang/common.yaml +++ b/tests/components/bang_bang/common.yaml @@ -10,7 +10,7 @@ sensor: - platform: template id: template_sensor1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return 42.0; } else { return 0.0; diff --git a/tests/components/binary_sensor_map/common.yaml b/tests/components/binary_sensor_map/common.yaml index c054022583..71f4c0158e 100644 --- a/tests/components/binary_sensor_map/common.yaml +++ b/tests/components/binary_sensor_map/common.yaml @@ -2,21 +2,21 @@ binary_sensor: - platform: template id: bin1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return true; } return false; - platform: template id: bin2 lambda: |- - if (millis() > 20000) { + if (esphome::millis() > 20000) { return true; } return false; - platform: template id: bin3 lambda: |- - if (millis() > 30000) { + if (esphome::millis() > 30000) { return true; } return false; diff --git a/tests/components/combination/common.yaml b/tests/components/combination/common.yaml index 0e5d512d08..bb05fa375b 100644 --- a/tests/components/combination/common.yaml +++ b/tests/components/combination/common.yaml @@ -2,14 +2,14 @@ sensor: - platform: template id: template_temperature1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return 0.6; } return 0.0; - platform: template id: template_temperature2 lambda: |- - if (millis() > 20000) { + if (esphome::millis() > 20000) { return 0.8; } return 0.0; diff --git a/tests/components/duty_time/common.yaml b/tests/components/duty_time/common.yaml index 761d10f16a..ffe62ec7fc 100644 --- a/tests/components/duty_time/common.yaml +++ b/tests/components/duty_time/common.yaml @@ -2,7 +2,7 @@ binary_sensor: - platform: template id: bin1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return true; } return false; diff --git a/tests/components/endstop/common.yaml b/tests/components/endstop/common.yaml index b92b1e13b9..317b31b1cb 100644 --- a/tests/components/endstop/common.yaml +++ b/tests/components/endstop/common.yaml @@ -2,7 +2,7 @@ binary_sensor: - platform: template id: bin1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return true; } return false; diff --git a/tests/components/lock/common.yaml b/tests/components/lock/common.yaml index 9ba7f34857..35907fe679 100644 --- a/tests/components/lock/common.yaml +++ b/tests/components/lock/common.yaml @@ -15,7 +15,7 @@ lock: id: test_lock1 name: Template Lock lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return LOCK_STATE_LOCKED; } return LOCK_STATE_UNLOCKED; diff --git a/tests/components/pid/common.yaml b/tests/components/pid/common.yaml index 262e75591e..e9478103f6 100644 --- a/tests/components/pid/common.yaml +++ b/tests/components/pid/common.yaml @@ -25,7 +25,7 @@ sensor: - platform: template id: template_sensor1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return 42.0; } return 0.0; diff --git a/tests/components/prometheus/common.yaml b/tests/components/prometheus/common.yaml index cf46e882a7..f9bd471ce7 100644 --- a/tests/components/prometheus/common.yaml +++ b/tests/components/prometheus/common.yaml @@ -33,7 +33,7 @@ sensor: - platform: template id: template_sensor1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return 42.0; } return 0.0; @@ -46,7 +46,7 @@ text_sensor: - platform: template id: template_text_sensor1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return {"Hello World"}; } return {"Goodbye (cruel) World"}; @@ -56,7 +56,7 @@ binary_sensor: - platform: template id: template_binary_sensor1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return true; } return false; @@ -65,7 +65,7 @@ switch: - platform: template id: template_switch1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return true; } return false; @@ -79,7 +79,7 @@ cover: - platform: template id: template_cover1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return COVER_OPEN; } return COVER_CLOSED; @@ -88,7 +88,7 @@ lock: - platform: template id: template_lock1 lambda: |- - if (millis() > 10000) { + if (esphome::millis() > 10000) { return LOCK_STATE_LOCKED; } return LOCK_STATE_UNLOCKED; From cce5b58de46a18f84f95160590064d82788b7f35 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 23 Oct 2025 08:19:48 -0600 Subject: [PATCH 8/9] Revert "[tests] Fix millis() ambiguity in component tests with gps component" This reverts commit f9b08491cc54d8fe24f3f5ce1a25ee257f5d0d09. --- tests/components/absolute_humidity/common.yaml | 4 ++-- tests/components/analog_threshold/common.yaml | 2 +- tests/components/bang_bang/common.yaml | 2 +- tests/components/binary_sensor_map/common.yaml | 6 +++--- tests/components/combination/common.yaml | 4 ++-- tests/components/duty_time/common.yaml | 2 +- tests/components/endstop/common.yaml | 2 +- tests/components/lock/common.yaml | 2 +- tests/components/pid/common.yaml | 2 +- tests/components/prometheus/common.yaml | 12 ++++++------ 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/components/absolute_humidity/common.yaml b/tests/components/absolute_humidity/common.yaml index f6b1c02886..026f88654f 100644 --- a/tests/components/absolute_humidity/common.yaml +++ b/tests/components/absolute_humidity/common.yaml @@ -6,14 +6,14 @@ sensor: - platform: template id: template_humidity lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return 0.6; } return 0.0; - platform: template id: template_temperature lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return 42.0; } return 0.0; diff --git a/tests/components/analog_threshold/common.yaml b/tests/components/analog_threshold/common.yaml index 7d9dc4bc9b..26c401b92a 100644 --- a/tests/components/analog_threshold/common.yaml +++ b/tests/components/analog_threshold/common.yaml @@ -3,7 +3,7 @@ sensor: id: template_sensor name: Template Sensor lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return 42.0; } return 0.0; diff --git a/tests/components/bang_bang/common.yaml b/tests/components/bang_bang/common.yaml index dc7798e2f2..5882025191 100644 --- a/tests/components/bang_bang/common.yaml +++ b/tests/components/bang_bang/common.yaml @@ -10,7 +10,7 @@ sensor: - platform: template id: template_sensor1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return 42.0; } else { return 0.0; diff --git a/tests/components/binary_sensor_map/common.yaml b/tests/components/binary_sensor_map/common.yaml index 71f4c0158e..c054022583 100644 --- a/tests/components/binary_sensor_map/common.yaml +++ b/tests/components/binary_sensor_map/common.yaml @@ -2,21 +2,21 @@ binary_sensor: - platform: template id: bin1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return true; } return false; - platform: template id: bin2 lambda: |- - if (esphome::millis() > 20000) { + if (millis() > 20000) { return true; } return false; - platform: template id: bin3 lambda: |- - if (esphome::millis() > 30000) { + if (millis() > 30000) { return true; } return false; diff --git a/tests/components/combination/common.yaml b/tests/components/combination/common.yaml index bb05fa375b..0e5d512d08 100644 --- a/tests/components/combination/common.yaml +++ b/tests/components/combination/common.yaml @@ -2,14 +2,14 @@ sensor: - platform: template id: template_temperature1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return 0.6; } return 0.0; - platform: template id: template_temperature2 lambda: |- - if (esphome::millis() > 20000) { + if (millis() > 20000) { return 0.8; } return 0.0; diff --git a/tests/components/duty_time/common.yaml b/tests/components/duty_time/common.yaml index ffe62ec7fc..761d10f16a 100644 --- a/tests/components/duty_time/common.yaml +++ b/tests/components/duty_time/common.yaml @@ -2,7 +2,7 @@ binary_sensor: - platform: template id: bin1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return true; } return false; diff --git a/tests/components/endstop/common.yaml b/tests/components/endstop/common.yaml index 317b31b1cb..b92b1e13b9 100644 --- a/tests/components/endstop/common.yaml +++ b/tests/components/endstop/common.yaml @@ -2,7 +2,7 @@ binary_sensor: - platform: template id: bin1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return true; } return false; diff --git a/tests/components/lock/common.yaml b/tests/components/lock/common.yaml index 35907fe679..9ba7f34857 100644 --- a/tests/components/lock/common.yaml +++ b/tests/components/lock/common.yaml @@ -15,7 +15,7 @@ lock: id: test_lock1 name: Template Lock lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return LOCK_STATE_LOCKED; } return LOCK_STATE_UNLOCKED; diff --git a/tests/components/pid/common.yaml b/tests/components/pid/common.yaml index e9478103f6..262e75591e 100644 --- a/tests/components/pid/common.yaml +++ b/tests/components/pid/common.yaml @@ -25,7 +25,7 @@ sensor: - platform: template id: template_sensor1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return 42.0; } return 0.0; diff --git a/tests/components/prometheus/common.yaml b/tests/components/prometheus/common.yaml index f9bd471ce7..cf46e882a7 100644 --- a/tests/components/prometheus/common.yaml +++ b/tests/components/prometheus/common.yaml @@ -33,7 +33,7 @@ sensor: - platform: template id: template_sensor1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return 42.0; } return 0.0; @@ -46,7 +46,7 @@ text_sensor: - platform: template id: template_text_sensor1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return {"Hello World"}; } return {"Goodbye (cruel) World"}; @@ -56,7 +56,7 @@ binary_sensor: - platform: template id: template_binary_sensor1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return true; } return false; @@ -65,7 +65,7 @@ switch: - platform: template id: template_switch1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return true; } return false; @@ -79,7 +79,7 @@ cover: - platform: template id: template_cover1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return COVER_OPEN; } return COVER_CLOSED; @@ -88,7 +88,7 @@ lock: - platform: template id: template_lock1 lambda: |- - if (esphome::millis() > 10000) { + if (millis() > 10000) { return LOCK_STATE_LOCKED; } return LOCK_STATE_UNLOCKED; From fdd453e88ac72475950d848f2bedaa4593ace8c5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 23 Oct 2025 09:02:08 -0600 Subject: [PATCH 9/9] fix --- script/analyze_component_buses.py | 1 + 1 file changed, 1 insertion(+) diff --git a/script/analyze_component_buses.py b/script/analyze_component_buses.py index 78f5ca3344..38d1f8c2b7 100755 --- a/script/analyze_component_buses.py +++ b/script/analyze_component_buses.py @@ -77,6 +77,7 @@ ISOLATED_COMPONENTS = { "esphome": "Defines devices/areas in esphome: section that are referenced in other sections - breaks when merged", "ethernet": "Defines ethernet: which conflicts with wifi: used by most components", "ethernet_info": "Related to ethernet component which conflicts with wifi", + "gps": "TinyGPSPlus library declares millis() function that creates ambiguity with ESPHome millis() macro when merged with components using millis() in lambdas", "lvgl": "Defines multiple SDL displays on host platform that conflict when merged with other display configs", "mapping": "Uses dict format for image/display sections incompatible with standard list format - ESPHome merge_config cannot handle", "openthread": "Conflicts with wifi: used by most components",