diff --git a/esphome/components/binary_sensor/__init__.py b/esphome/components/binary_sensor/__init__.py index 5800e0bd9e..900cb0ef03 100644 --- a/esphome/components/binary_sensor/__init__.py +++ b/esphome/components/binary_sensor/__init__.py @@ -560,6 +560,11 @@ _CALLBACK_AUTOMATIONS = ( async def _build_binary_sensor_automations(var, config): await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS) + if CONF_ON_CLICK in config or CONF_ON_DOUBLE_CLICK in config: + cg.add_define("USE_BINARY_SENSOR_CLICK_TRIGGER") + if CONF_ON_MULTI_CLICK in config: + cg.add_define("USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER") + for conf in config.get(CONF_ON_CLICK, []): trigger = cg.new_Pvariable( conf[CONF_TRIGGER_ID], var, conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH] @@ -673,3 +678,19 @@ async def to_code(config): async def binary_sensor_invalidate_state_to_code(config, action_id, template_arg, args): paren = await cg.get_variable(config[CONF_ID]) return cg.new_Pvariable(action_id, template_arg, paren) + + +def FILTER_SOURCE_FILES() -> list[str]: + """automation.cpp only implements the click/double_click/multi_click + triggers and filter.cpp is fully #ifdef'd on USE_BINARY_SENSOR_FILTER; + skip copying them when unused so they are not opened and parsed.""" + defines = {define.name for define in CORE.defines} + files: list[str] = [] + if not defines & { + "USE_BINARY_SENSOR_CLICK_TRIGGER", + "USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER", + }: + files.append("automation.cpp") + if "USE_BINARY_SENSOR_FILTER" not in defines: + files.append("filter.cpp") + return files diff --git a/esphome/components/binary_sensor/automation.cpp b/esphome/components/binary_sensor/automation.cpp index b13e4a88dd..1a3c1f7536 100644 --- a/esphome/components/binary_sensor/automation.cpp +++ b/esphome/components/binary_sensor/automation.cpp @@ -1,8 +1,13 @@ +#include "esphome/core/defines.h" +#if defined(USE_BINARY_SENSOR_CLICK_TRIGGER) || defined(USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER) + #include "automation.h" #include "esphome/core/log.h" namespace esphome::binary_sensor { +#ifdef USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER + static const char *const TAG = "binary_sensor.automation"; // MultiClickTrigger timeout IDs. @@ -120,6 +125,9 @@ void MultiClickTriggerBase::trigger_() { this->trigger(); } +#endif // USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER + +#ifdef USE_BINARY_SENSOR_CLICK_TRIGGER bool match_interval(uint32_t min_length, uint32_t max_length, uint32_t length) { if (max_length == 0) { return length >= min_length; @@ -127,4 +135,8 @@ bool match_interval(uint32_t min_length, uint32_t max_length, uint32_t length) { return length >= min_length && length <= max_length; } } +#endif // USE_BINARY_SENSOR_CLICK_TRIGGER + } // namespace esphome::binary_sensor + +#endif // USE_BINARY_SENSOR_CLICK_TRIGGER || USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index d6ed6d9399..3474a3a64d 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -3450,3 +3450,12 @@ def process_stacktrace(config, line, backtrace_state): _decode_pc(config, addr.group()) return backtrace_state + + +def FILTER_SOURCE_FILES() -> list[str]: + """gpio.cpp only implements ESP32InternalGPIOPin (and its ISR helpers), + which is instantiated solely by the pin schema codegen; skip copying it + when the config uses no internal GPIO pins.""" + if not any(define.name == "USE_ESP32_INTERNAL_GPIO" for define in CORE.defines): + return ["gpio.cpp"] + return [] diff --git a/esphome/components/esp32/gpio.cpp b/esphome/components/esp32/gpio.cpp index 4b53d3a172..73e23cba7f 100644 --- a/esphome/components/esp32/gpio.cpp +++ b/esphome/components/esp32/gpio.cpp @@ -1,4 +1,5 @@ -#ifdef USE_ESP32 +#include "esphome/core/defines.h" +#if defined(USE_ESP32) && defined(USE_ESP32_INTERNAL_GPIO) #include "gpio.h" #include "esphome/core/log.h" @@ -204,4 +205,4 @@ void IRAM_ATTR ISRInternalGPIOPin::pin_mode(gpio::Flags flags) { } // namespace esphome -#endif // USE_ESP32 +#endif // USE_ESP32 && USE_ESP32_INTERNAL_GPIO diff --git a/esphome/components/esp32/gpio.py b/esphome/components/esp32/gpio.py index 321dd3d498..98aac209ec 100644 --- a/esphome/components/esp32/gpio.py +++ b/esphome/components/esp32/gpio.py @@ -257,6 +257,7 @@ ESP32_PIN_SCHEMA = cv.All( @pins.PIN_SCHEMA_REGISTRY.register(PLATFORM_ESP32, ESP32_PIN_SCHEMA) async def esp32_pin_to_code(config): + cg.add_define("USE_ESP32_INTERNAL_GPIO") var = cg.new_Pvariable(config[CONF_ID]) num = config[CONF_NUMBER] cg.add(var.set_pin(getattr(gpio_num_t, f"GPIO_NUM_{num}"))) diff --git a/esphome/components/sensor/__init__.py b/esphome/components/sensor/__init__.py index 6ad76046a1..dfa56a0612 100644 --- a/esphome/components/sensor/__init__.py +++ b/esphome/components/sensor/__init__.py @@ -1303,3 +1303,11 @@ def _lstsq(a, b): @coroutine_with_priority(CoroPriority.CORE) async def to_code(config): cg.add_global(sensor_ns.using) + + +def FILTER_SOURCE_FILES() -> list[str]: + """filter.cpp is fully #ifdef'd on USE_SENSOR_FILTER; skip copying it + when no sensor uses filters so it is not opened and parsed.""" + if not any(define.name == "USE_SENSOR_FILTER" for define in CORE.defines): + return ["filter.cpp"] + return [] diff --git a/esphome/components/text_sensor/__init__.py b/esphome/components/text_sensor/__init__.py index a3f4999a8f..8fbef640d2 100644 --- a/esphome/components/text_sensor/__init__.py +++ b/esphome/components/text_sensor/__init__.py @@ -256,3 +256,11 @@ async def text_sensor_state_to_code(config, condition_id, template_arg, args): templ = await cg.templatable(config[CONF_STATE], args, cg.std_string) cg.add(var.set_state(templ)) return var + + +def FILTER_SOURCE_FILES() -> list[str]: + """filter.cpp is fully #ifdef'd on USE_TEXT_SENSOR_FILTER; skip copying it + when no text sensor uses filters so it is not opened and parsed.""" + if not any(define.name == "USE_TEXT_SENSOR_FILTER" for define in CORE.defines): + return ["filter.cpp"] + return [] diff --git a/esphome/core/defines.h b/esphome/core/defines.h index bb4960aec7..20aca3776f 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -43,7 +43,9 @@ #define USE_ALARM_CONTROL_PANEL #define USE_AREAS #define USE_BINARY_SENSOR +#define USE_BINARY_SENSOR_CLICK_TRIGGER #define USE_BINARY_SENSOR_FILTER +#define USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER #define USE_BLE_DEVICE_IRK #define USE_BUTTON #define USE_CAMERA @@ -281,6 +283,7 @@ // ESP32-specific feature flags #ifdef USE_ESP32 #define USE_ESP32_CRASH_HANDLER +#define USE_ESP32_INTERNAL_GPIO #define USE_MQTT_IDF_ENQUEUE #define USE_ESPHOME_TASK_LOG_BUFFER #define ESPHOME_TASK_LOG_BUFFER_SIZE 768