Merge branch 'dev' into buildinfo

This commit is contained in:
David Woodhouse
2025-12-17 22:59:57 +00:00
committed by GitHub
12 changed files with 68 additions and 49 deletions
@@ -11,6 +11,7 @@ CODEOWNERS = ["@neffs", "@kbx81"]
AUTO_LOAD = ["bme68x_bsec2"]
DEPENDENCIES = ["i2c"]
MULTI_CONF = True
bme68x_bsec2_i2c_ns = cg.esphome_ns.namespace("bme68x_bsec2_i2c")
BME68xBSEC2I2CComponent = bme68x_bsec2_i2c_ns.class_(
@@ -7,7 +7,7 @@ namespace copy {
static const char *const TAG = "copy.select";
void CopySelect::setup() {
source_->add_on_state_callback([this](const std::string &value, size_t index) { this->publish_state(index); });
source_->add_on_state_callback([this](size_t index) { this->publish_state(index); });
traits.set_options(source_->traits.get_options());
-9
View File
@@ -982,15 +982,6 @@ async def to_code(config):
cg.add_platformio_option("framework", "arduino, espidf")
cg.add_build_flag("-DUSE_ARDUINO")
cg.add_build_flag("-DUSE_ESP32_FRAMEWORK_ARDUINO")
cg.add_platformio_option(
"board_build.embed_txtfiles",
[
"managed_components/espressif__esp_insights/server_certs/https_server.crt",
"managed_components/espressif__esp_rainmaker/server_certs/rmaker_mqtt_server.crt",
"managed_components/espressif__esp_rainmaker/server_certs/rmaker_claim_service_server.crt",
"managed_components/espressif__esp_rainmaker/server_certs/rmaker_ota_server.crt",
],
)
cg.add_define(
"USE_ARDUINO_VERSION_CODE",
cg.RawExpression(
@@ -5,6 +5,7 @@ import json # noqa: E402
import os # noqa: E402
import pathlib # noqa: E402
import shutil # noqa: E402
from glob import glob # noqa: E402
def merge_factory_bin(source, target, env):
@@ -126,3 +127,14 @@ def esp32_copy_ota_bin(source, target, env):
# Run merge first, then ota copy second
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", merge_factory_bin) # noqa: F821
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_copy_ota_bin) # noqa: F821
# Find server certificates in managed components and generate .S files.
# Workaround for PlatformIO not processing target_add_binary_data() from managed component CMakeLists.
project_dir = env.subst("$PROJECT_DIR")
managed_components = os.path.join(project_dir, "managed_components")
if os.path.isdir(managed_components):
for cert_file in glob(os.path.join(managed_components, "**/server_certs/*.crt"), recursive=True):
try:
env.FileToAsm(cert_file, FILE_TYPE="TEXT")
except Exception as e:
print(f"Error processing {os.path.basename(cert_file)}: {e}")
+3 -1
View File
@@ -3,7 +3,7 @@ import logging
from esphome import automation, pins
import esphome.codegen as cg
from esphome.components import i2c
from esphome.components.esp32 import add_idf_component
from esphome.components.esp32 import add_idf_component, add_idf_sdkconfig_option
from esphome.components.psram import DOMAIN as psram_domain
import esphome.config_validation as cv
from esphome.const import (
@@ -352,6 +352,8 @@ async def to_code(config):
cg.add_define("USE_CAMERA")
add_idf_component(name="espressif/esp32-camera", ref="2.1.1")
add_idf_sdkconfig_option("CONFIG_SCCB_HARDWARE_I2C_DRIVER_NEW", True)
add_idf_sdkconfig_option("CONFIG_SCCB_HARDWARE_I2C_DRIVER_LEGACY", False)
for conf in config.get(CONF_ON_STREAM_START, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
+1 -2
View File
@@ -21,8 +21,7 @@ void MQTTSelectComponent::setup() {
call.set_option(state);
call.perform();
});
this->select_->add_on_state_callback(
[this](const std::string &state, size_t index) { this->publish_state(this->select_->option_at(index)); });
this->select_->add_on_state_callback([this](size_t index) { this->publish_state(this->select_->option_at(index)); });
}
void MQTTSelectComponent::dump_config() {
+5 -9
View File
@@ -7,10 +7,10 @@ from esphome.const import (
CONF_UPDATE_INTERVAL,
DEVICE_CLASS_PM25,
ICON_BLUR,
SCHEDULER_DONT_RUN,
STATE_CLASS_MEASUREMENT,
UNIT_MICROGRAMS_PER_CUBIC_METER,
)
from esphome.core import TimePeriodMilliseconds
CODEOWNERS = ["@habbie"]
DEPENDENCIES = ["uart"]
@@ -41,16 +41,12 @@ CONFIG_SCHEMA = cv.All(
def validate_interval_uart(config):
require_tx = False
interval = config.get(CONF_UPDATE_INTERVAL)
if isinstance(interval, TimePeriodMilliseconds):
# 'never' is encoded as a very large int, not as a TimePeriodMilliseconds objects
require_tx = True
uart.final_validate_device_schema(
"pm1006", baud_rate=9600, require_rx=True, require_tx=require_tx
"pm1006",
baud_rate=9600,
require_rx=True,
require_tx=interval.total_milliseconds != SCHEDULER_DONT_RUN,
)(config)
+6 -2
View File
@@ -8,9 +8,13 @@ namespace esphome::select {
class SelectStateTrigger : public Trigger<std::string, size_t> {
public:
explicit SelectStateTrigger(Select *parent) {
parent->add_on_state_callback([this](const std::string &value, size_t index) { this->trigger(value, index); });
explicit SelectStateTrigger(Select *parent) : parent_(parent) {
parent->add_on_state_callback(
[this](size_t index) { this->trigger(std::string(this->parent_->option_at(index)), index); });
}
protected:
Select *parent_;
};
template<typename... Ts> class SelectSetAction : public Action<Ts...> {
+2 -3
View File
@@ -32,8 +32,7 @@ void Select::publish_state(size_t index) {
this->state = option; // Update deprecated member for backward compatibility
#pragma GCC diagnostic pop
ESP_LOGD(TAG, "'%s': Sending state %s (index %zu)", this->get_name().c_str(), option, index);
// Callback signature requires std::string, create temporary for compatibility
this->state_callback_.call(std::string(option), index);
this->state_callback_.call(index);
#if defined(USE_SELECT) && defined(USE_CONTROLLER_REGISTRY)
ControllerRegistry::notify_select_update(this);
#endif
@@ -41,7 +40,7 @@ void Select::publish_state(size_t index) {
const char *Select::current_option() const { return this->has_state() ? this->option_at(this->active_index_) : ""; }
void Select::add_on_state_callback(std::function<void(std::string, size_t)> &&callback) {
void Select::add_on_state_callback(std::function<void(size_t)> &&callback) {
this->state_callback_.add(std::move(callback));
}
+2 -2
View File
@@ -75,7 +75,7 @@ class Select : public EntityBase {
/// Return the option value at the provided index offset (as const char* from flash).
const char *option_at(size_t index) const;
void add_on_state_callback(std::function<void(std::string, size_t)> &&callback);
void add_on_state_callback(std::function<void(size_t)> &&callback);
protected:
friend class SelectCall;
@@ -111,7 +111,7 @@ class Select : public EntityBase {
}
}
CallbackManager<void(std::string, size_t)> state_callback_;
CallbackManager<void(size_t)> state_callback_;
};
} // namespace esphome::select
+19 -7
View File
@@ -253,19 +253,31 @@ def main():
print(f"Split {args.split_at}/{args.split_num}: checking {len(files)} files")
# Print file count before adding header file
print(f"\nTotal files to check: {len(files)}")
print(f"\nTotal cpp files to check: {len(files)}")
# Add header file for checking (before early exit check)
if args.all_headers and args.split_at in (None, 1):
# When --changed is used, only include changed headers instead of all headers
if args.changed:
all_headers = [
os.path.relpath(p, cwd) for p in git_ls_files(["esphome/**/*.h"])
]
changed_headers = filter_changed(all_headers)
if changed_headers:
build_all_include(changed_headers)
files.insert(0, temp_header_file)
else:
print("No changed headers to check")
else:
build_all_include()
files.insert(0, temp_header_file)
print(f"Added all-include header file, new total: {len(files)}")
# Early exit if no files to check
if not files:
print("No files to check - exiting early")
return 0
# Only build header file if we have actual files to check
if args.all_headers and args.split_at in (None, 1):
build_all_include()
files.insert(0, temp_header_file)
print(f"Added all-include header file, new total: {len(files)}")
# Print final file list before loading idedata
print_file_list(files, "Final files to process:")
+16 -13
View File
@@ -156,22 +156,25 @@ def print_error_for_file(file: str | Path, body: str | None) -> None:
print()
def build_all_include() -> None:
# Build a cpp file that includes all header files in this repo.
# Otherwise header-only integrations would not be tested by clang-tidy
def build_all_include(header_files: list[str] | None = None) -> None:
# Build a cpp file that includes header files for clang-tidy to check.
# If header_files is provided, only include those headers.
# Otherwise, include all header files in the esphome directory.
# Use git ls-files to find all .h files in the esphome directory
# This is much faster than walking the filesystem
cmd = ["git", "ls-files", "esphome/**/*.h"]
proc = subprocess.run(cmd, capture_output=True, text=True, check=True)
if header_files is None:
# Use git ls-files to find all .h files in the esphome directory
# This is much faster than walking the filesystem
cmd = ["git", "ls-files", "esphome/**/*.h"]
proc = subprocess.run(cmd, capture_output=True, text=True, check=True)
# Process git output - git already returns paths relative to repo root
headers = [
f'#include "{include_p}"'
for line in proc.stdout.strip().split("\n")
if (include_p := line.replace(os.path.sep, "/"))
]
# Process git output - git already returns paths relative to repo root
header_files = [
line.replace(os.path.sep, "/")
for line in proc.stdout.strip().split("\n")
if line
]
headers = [f'#include "{h}"' for h in header_files]
headers.sort()
headers.append("")
content = "\n".join(headers)