diff --git a/esphome/components/i2s_audio/speaker/__init__.py b/esphome/components/i2s_audio/speaker/__init__.py index 0355c16321..eb6bb329ad 100644 --- a/esphome/components/i2s_audio/speaker/__init__.py +++ b/esphome/components/i2s_audio/speaker/__init__.py @@ -2,7 +2,14 @@ from esphome import pins import esphome.codegen as cg from esphome.components import esp32, speaker import esphome.config_validation as cv -from esphome.const import CONF_CHANNEL, CONF_ID, CONF_MODE, CONF_TIMEOUT +from esphome.const import ( + CONF_BUFFER_DURATION, + CONF_CHANNEL, + CONF_ID, + CONF_MODE, + CONF_NEVER, + CONF_TIMEOUT, +) from .. import ( CONF_I2S_DOUT_PIN, @@ -24,10 +31,8 @@ I2SAudioSpeaker = i2s_audio_ns.class_( "I2SAudioSpeaker", cg.Component, speaker.Speaker, I2SAudioOut ) -CONF_BUFFER_DURATION = "buffer_duration" CONF_DAC_TYPE = "dac_type" CONF_I2S_COMM_FMT = "i2s_comm_fmt" -CONF_NEVER = "never" i2s_dac_mode_t = cg.global_ns.enum("i2s_dac_mode_t") INTERNAL_DAC_OPTIONS = { diff --git a/esphome/const.py b/esphome/const.py index ab41d8cbc2..16bfda9478 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -94,6 +94,7 @@ CONF_BRIGHTNESS = "brightness" CONF_BRIGHTNESS_LIMITS = "brightness_limits" CONF_BROKER = "broker" CONF_BSSID = "bssid" +CONF_BUFFER_DURATION = "buffer_duration" CONF_BUFFER_SIZE = "buffer_size" CONF_BUILD_PATH = "build_path" CONF_BUS_VOLTAGE = "bus_voltage" @@ -527,6 +528,7 @@ CONF_NAME_FONT = "name_font" CONF_NBITS = "nbits" CONF_NEC = "nec" CONF_NETWORKS = "networks" +CONF_NEVER = "never" CONF_NEW_PASSWORD = "new_password" CONF_NITROGEN_DIOXIDE = "nitrogen_dioxide" CONF_NOISE_LEVEL = "noise_level" @@ -615,6 +617,7 @@ CONF_OTA = "ota" CONF_OUTDOOR_TEMPERATURE = "outdoor_temperature" CONF_OUTPUT = "output" CONF_OUTPUT_ID = "output_id" +CONF_OUTPUT_SPEAKER = "output_speaker" CONF_OUTPUTS = "outputs" CONF_OVERSAMPLING = "oversampling" CONF_PACKAGES = "packages" @@ -859,6 +862,7 @@ CONF_TARGET_TEMPERATURE_LOW = "target_temperature_low" CONF_TARGET_TEMPERATURE_LOW_COMMAND_TOPIC = "target_temperature_low_command_topic" CONF_TARGET_TEMPERATURE_LOW_STATE_TOPIC = "target_temperature_low_state_topic" CONF_TARGET_TEMPERATURE_STATE_TOPIC = "target_temperature_state_topic" +CONF_TASK_STACK_IN_PSRAM = "task_stack_in_psram" CONF_TEMPERATURE = "temperature" CONF_TEMPERATURE_COMPENSATION = "temperature_compensation" CONF_TEMPERATURE_OFFSET = "temperature_offset" diff --git a/esphome/core/__init__.py b/esphome/core/__init__.py index 59cea6f09b..2d856d99c5 100644 --- a/esphome/core/__init__.py +++ b/esphome/core/__init__.py @@ -689,7 +689,7 @@ class EsphomeCore: _LOGGER.debug("Adding: %s", expression) return expression - def add_global(self, expression): + def add_global(self, expression, prepend=False): from esphome.cpp_generator import Expression, Statement, statement if isinstance(expression, Expression): @@ -698,7 +698,10 @@ class EsphomeCore: raise ValueError( f"Add '{expression}' must be expression or statement, not {type(expression)}" ) - self.global_statements.append(expression) + if prepend: + self.global_statements.insert(0, expression) + else: + self.global_statements.append(expression) _LOGGER.debug("Adding global: %s", expression) return expression diff --git a/esphome/core/config.py b/esphome/core/config.py index 06ae1d7747..7152414463 100644 --- a/esphome/core/config.py +++ b/esphome/core/config.py @@ -72,6 +72,9 @@ def validate_hostname(config): def valid_include(value): + # Look for "<...>" includes + if value.startswith("<") and value.endswith(">"): + return value try: return cv.directory(value) except cv.Invalid: @@ -360,7 +363,19 @@ async def to_code(config): CORE.add_job(add_arduino_global_workaround) if config[CONF_INCLUDES]: - CORE.add_job(add_includes, config[CONF_INCLUDES]) + # Get the <...> includes + system_includes = [] + other_includes = [] + for include in config[CONF_INCLUDES]: + if include.startswith("<") and include.endswith(">"): + system_includes.append(include) + else: + other_includes.append(include) + # <...> includes should be at the start + for include in system_includes: + cg.add_global(cg.RawStatement(f"#include {include}"), prepend=True) + # Other includes should be at the end + CORE.add_job(add_includes, other_includes) if project_conf := config.get(CONF_PROJECT): cg.add_define("ESPHOME_PROJECT_NAME", project_conf[CONF_NAME]) diff --git a/esphome/cpp_generator.py b/esphome/cpp_generator.py index 7a82d5cba1..4e283868e1 100644 --- a/esphome/cpp_generator.py +++ b/esphome/cpp_generator.py @@ -588,9 +588,9 @@ def add(expression: Union[Expression, Statement]): CORE.add(expression) -def add_global(expression: Union[SafeExpType, Statement]): +def add_global(expression: Union[SafeExpType, Statement], prepend: bool = False): """Add an expression to the codegen global storage (above setup()).""" - CORE.add_global(expression) + CORE.add_global(expression, prepend) def add_library(name: str, version: Optional[str], repository: Optional[str] = None): diff --git a/requirements.txt b/requirements.txt index d96004c8ef..0d93c3cc2d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,7 @@ esptool==4.7.0 click==8.1.7 esphome-dashboard==20241217.1 aioesphomeapi==24.6.2 -zeroconf==0.132.2 +zeroconf==0.143.0 puremagic==1.27 ruamel.yaml==0.18.6 # dashboard_import glyphsets==1.0.0