From 89c3340ef6f6c24b5fe4f6e90ef4549e36aeb1d9 Mon Sep 17 00:00:00 2001 From: mrtoy-me <118446898+mrtoy-me@users.noreply.github.com> Date: Fri, 3 Oct 2025 23:06:16 +1000 Subject: [PATCH 1/8] [mpr121] remove delay (#10963) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- esphome/components/mpr121/mpr121.cpp | 75 ++++++++++++++-------------- esphome/components/mpr121/mpr121.h | 2 +- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/esphome/components/mpr121/mpr121.cpp b/esphome/components/mpr121/mpr121.cpp index 074bc79ea2..60d8235b03 100644 --- a/esphome/components/mpr121/mpr121.cpp +++ b/esphome/components/mpr121/mpr121.cpp @@ -13,45 +13,46 @@ static const char *const TAG = "mpr121"; void MPR121Component::setup() { // soft reset device this->write_byte(MPR121_SOFTRESET, 0x63); - delay(100); // NOLINT - if (!this->write_byte(MPR121_ECR, 0x0)) { - this->error_code_ = COMMUNICATION_FAILED; - this->mark_failed(); - return; - } + this->set_timeout(100, [this]() { + if (!this->write_byte(MPR121_ECR, 0x0)) { + this->error_code_ = COMMUNICATION_FAILED; + this->mark_failed(); + return; + } + // set touch sensitivity for all 12 channels + for (auto *channel : this->channels_) { + channel->setup(); + } + this->write_byte(MPR121_MHDR, 0x01); + this->write_byte(MPR121_NHDR, 0x01); + this->write_byte(MPR121_NCLR, 0x0E); + this->write_byte(MPR121_FDLR, 0x00); - // set touch sensitivity for all 12 channels - for (auto *channel : this->channels_) { - channel->setup(); - } - this->write_byte(MPR121_MHDR, 0x01); - this->write_byte(MPR121_NHDR, 0x01); - this->write_byte(MPR121_NCLR, 0x0E); - this->write_byte(MPR121_FDLR, 0x00); + this->write_byte(MPR121_MHDF, 0x01); + this->write_byte(MPR121_NHDF, 0x05); + this->write_byte(MPR121_NCLF, 0x01); + this->write_byte(MPR121_FDLF, 0x00); - this->write_byte(MPR121_MHDF, 0x01); - this->write_byte(MPR121_NHDF, 0x05); - this->write_byte(MPR121_NCLF, 0x01); - this->write_byte(MPR121_FDLF, 0x00); + this->write_byte(MPR121_NHDT, 0x00); + this->write_byte(MPR121_NCLT, 0x00); + this->write_byte(MPR121_FDLT, 0x00); - this->write_byte(MPR121_NHDT, 0x00); - this->write_byte(MPR121_NCLT, 0x00); - this->write_byte(MPR121_FDLT, 0x00); + this->write_byte(MPR121_DEBOUNCE, 0); + // default, 16uA charge current + this->write_byte(MPR121_CONFIG1, 0x10); + // 0.5uS encoding, 1ms period + this->write_byte(MPR121_CONFIG2, 0x20); - this->write_byte(MPR121_DEBOUNCE, 0); - // default, 16uA charge current - this->write_byte(MPR121_CONFIG1, 0x10); - // 0.5uS encoding, 1ms period - this->write_byte(MPR121_CONFIG2, 0x20); + // Write the Electrode Configuration Register + // * Highest 2 bits is "Calibration Lock", which we set to a value corresponding to 5 bits. + // * The 2 bits below is "Proximity Enable" and are left at 0. + // * The 4 least significant bits control how many electrodes are enabled. Electrodes are enabled + // as a range, starting at 0 up to the highest channel index used. + this->write_byte(MPR121_ECR, 0x80 | (this->max_touch_channel_ + 1)); - // Write the Electrode Configuration Register - // * Highest 2 bits is "Calibration Lock", which we set to a value corresponding to 5 bits. - // * The 2 bits below is "Proximity Enable" and are left at 0. - // * The 4 least significant bits control how many electrodes are enabled. Electrodes are enabled - // as a range, starting at 0 up to the highest channel index used. - this->write_byte(MPR121_ECR, 0x80 | (this->max_touch_channel_ + 1)); - - this->flush_gpio_(); + this->flush_gpio_(); + this->setup_complete_ = true; + }); } void MPR121Component::set_touch_debounce(uint8_t debounce) { @@ -73,15 +74,15 @@ void MPR121Component::dump_config() { case COMMUNICATION_FAILED: ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL); break; - case WRONG_CHIP_STATE: - ESP_LOGE(TAG, "MPR121 has wrong default value for CONFIG2?"); - break; case NONE: default: break; } } void MPR121Component::loop() { + if (!this->setup_complete_) + return; + uint16_t val = 0; this->read_byte_16(MPR121_TOUCHSTATUS_L, &val); diff --git a/esphome/components/mpr121/mpr121.h b/esphome/components/mpr121/mpr121.h index eb2e2edc57..8f942f3e98 100644 --- a/esphome/components/mpr121/mpr121.h +++ b/esphome/components/mpr121/mpr121.h @@ -80,6 +80,7 @@ class MPR121Component : public Component, public i2c::I2CDevice { void pin_mode(uint8_t ionum, gpio::Flags flags); protected: + bool setup_complete_{false}; std::vector channels_{}; uint8_t debounce_{0}; uint8_t touch_threshold_{}; @@ -88,7 +89,6 @@ class MPR121Component : public Component, public i2c::I2CDevice { enum ErrorCode { NONE = 0, COMMUNICATION_FAILED, - WRONG_CHIP_STATE, } error_code_{NONE}; bool flush_gpio_(); From 2b389bb8f2a3d02ede8b7cafa32cdf9351145382 Mon Sep 17 00:00:00 2001 From: mrtoy-me <118446898+mrtoy-me@users.noreply.github.com> Date: Fri, 3 Oct 2025 23:40:43 +1000 Subject: [PATCH 2/8] [sps30] remove delay (#10964) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- esphome/components/sps30/sps30.cpp | 30 +++++++++++++++++------------- esphome/components/sps30/sps30.h | 3 +++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/esphome/components/sps30/sps30.cpp b/esphome/components/sps30/sps30.cpp index b99bf416d6..dc14e3a610 100644 --- a/esphome/components/sps30/sps30.cpp +++ b/esphome/components/sps30/sps30.cpp @@ -45,24 +45,26 @@ void SPS30Component::setup() { } ESP_LOGV(TAG, " Serial number: %s", this->serial_number_); - bool result; if (this->fan_interval_.has_value()) { // override default value - result = this->write_command(SPS30_CMD_SET_AUTOMATIC_CLEANING_INTERVAL_SECONDS, this->fan_interval_.value()); + this->result_ = + this->write_command(SPS30_CMD_SET_AUTOMATIC_CLEANING_INTERVAL_SECONDS, this->fan_interval_.value()); } else { - result = this->write_command(SPS30_CMD_SET_AUTOMATIC_CLEANING_INTERVAL_SECONDS); - } - if (result) { - delay(20); - uint16_t secs[2]; - if (this->read_data(secs, 2)) { - this->fan_interval_ = secs[0] << 16 | secs[1]; - } + this->result_ = this->write_command(SPS30_CMD_SET_AUTOMATIC_CLEANING_INTERVAL_SECONDS); } - this->status_clear_warning(); - this->skipped_data_read_cycles_ = 0; - this->start_continuous_measurement_(); + this->set_timeout(20, [this]() { + if (this->result_) { + uint16_t secs[2]; + if (this->read_data(secs, 2)) { + this->fan_interval_ = secs[0] << 16 | secs[1]; + } + } + this->status_clear_warning(); + this->skipped_data_read_cycles_ = 0; + this->start_continuous_measurement_(); + this->setup_complete_ = true; + }); }); } @@ -111,6 +113,8 @@ void SPS30Component::dump_config() { } void SPS30Component::update() { + if (!this->setup_complete_) + return; /// Check if warning flag active (sensor reconnected?) if (this->status_has_warning()) { ESP_LOGD(TAG, "Reconnecting"); diff --git a/esphome/components/sps30/sps30.h b/esphome/components/sps30/sps30.h index 461a770ab6..cab5a075a0 100644 --- a/esphome/components/sps30/sps30.h +++ b/esphome/components/sps30/sps30.h @@ -30,9 +30,12 @@ class SPS30Component : public PollingComponent, public sensirion_common::Sensiri bool start_fan_cleaning(); protected: + bool result_{false}; + bool setup_complete_{false}; uint16_t raw_firmware_version_; char serial_number_[17] = {0}; /// Terminating NULL character uint8_t skipped_data_read_cycles_ = 0; + bool start_continuous_measurement_(); enum ErrorCode : uint8_t { From 14a23101f2ddf9e3473451d9779fe0b712d592a0 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Fri, 3 Oct 2025 11:35:55 -0400 Subject: [PATCH 3/8] [core] Fix MQTT import (#10982) --- esphome/__main__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/esphome/__main__.py b/esphome/__main__.py index 38edcb070f..b0f541f521 100644 --- a/esphome/__main__.py +++ b/esphome/__main__.py @@ -14,9 +14,11 @@ from typing import Protocol import argcomplete +# Note: Do not import modules from esphome.components here, as this would +# cause them to be loaded before external components are processed, resulting +# in the built-in version being used instead of the external component one. from esphome import const, writer, yaml_util import esphome.codegen as cg -from esphome.components.mqtt import CONF_DISCOVER_IP from esphome.config import iter_component_configs, read_config, strip_default_ids from esphome.const import ( ALLOWED_NAME_CHARS, @@ -240,6 +242,8 @@ def has_ota() -> bool: def has_mqtt_ip_lookup() -> bool: """Check if MQTT is available and IP lookup is supported.""" + from esphome.components.mqtt import CONF_DISCOVER_IP + if CONF_MQTT not in CORE.config: return False # Default Enabled From ca0e738799f62e8fc2170fb6dd2ba03e5f117355 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 3 Oct 2025 10:50:21 -0500 Subject: [PATCH 4/8] [logger] Fix line number wrapping bug for files with >999 lines (#10979) --- esphome/components/logger/logger.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/esphome/components/logger/logger.h b/esphome/components/logger/logger.h index 7d4c14df0b..f0e0ed9a27 100644 --- a/esphome/components/logger/logger.h +++ b/esphome/components/logger/logger.h @@ -355,9 +355,18 @@ class Logger : public Component { buffer[pos++] = '['; copy_string(buffer, pos, tag); buffer[pos++] = ':'; - buffer[pos++] = '0' + (line / 100) % 10; - buffer[pos++] = '0' + (line / 10) % 10; - buffer[pos++] = '0' + line % 10; + // Format line number without modulo operations (passed by value, safe to mutate) + if (line > 999) [[unlikely]] { + int thousands = line / 1000; + buffer[pos++] = '0' + thousands; + line -= thousands * 1000; + } + int hundreds = line / 100; + int remainder = line - hundreds * 100; + int tens = remainder / 10; + buffer[pos++] = '0' + hundreds; + buffer[pos++] = '0' + tens; + buffer[pos++] = '0' + (remainder - tens * 10); buffer[pos++] = ']'; #if defined(USE_ESP32) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR) From 6f8e82aeb682533d3a602dad1c05d3fe91e57860 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 14:27:29 -0500 Subject: [PATCH 5/8] Bump actions/stale from 10.0.0 to 10.1.0 (#11001) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index f57f0987ec..63a8ade37f 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Stale - uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0 + uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0 with: debug-only: ${{ github.ref != 'refs/heads/dev' }} # Dry-run when not run on dev branch remove-stale-when-updated: true From 2596b6096fcac0ace8ed4462da423a88806aa627 Mon Sep 17 00:00:00 2001 From: Tucker Kern Date: Fri, 3 Oct 2025 13:28:38 -0600 Subject: [PATCH 6/8] Fix log level selector when selecting levels above INFO (#10368) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- .../logger/select/logger_level_select.cpp | 13 ++++++------- .../components/logger/select/logger_level_select.h | 7 +++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/esphome/components/logger/select/logger_level_select.cpp b/esphome/components/logger/select/logger_level_select.cpp index d9c950ce3c..6d60a3ae47 100644 --- a/esphome/components/logger/select/logger_level_select.cpp +++ b/esphome/components/logger/select/logger_level_select.cpp @@ -3,11 +3,10 @@ namespace esphome::logger { void LoggerLevelSelect::publish_state(int level) { - auto value = this->at(level); - if (!value) { + const auto &option = this->at(level_to_index(level)); + if (!option) return; - } - Select::publish_state(value.value()); + Select::publish_state(option.value()); } void LoggerLevelSelect::setup() { @@ -16,10 +15,10 @@ void LoggerLevelSelect::setup() { } void LoggerLevelSelect::control(const std::string &value) { - auto level = this->index_of(value); - if (!level) + const auto index = this->index_of(value); + if (!index) return; - this->parent_->set_log_level(level.value()); + this->parent_->set_log_level(index_to_level(index.value())); } } // namespace esphome::logger diff --git a/esphome/components/logger/select/logger_level_select.h b/esphome/components/logger/select/logger_level_select.h index f31a6f6cdb..0631eca45d 100644 --- a/esphome/components/logger/select/logger_level_select.h +++ b/esphome/components/logger/select/logger_level_select.h @@ -3,11 +3,18 @@ #include "esphome/components/select/select.h" #include "esphome/core/component.h" #include "esphome/components/logger/logger.h" + namespace esphome::logger { class LoggerLevelSelect : public Component, public select::Select, public Parented { public: void publish_state(int level); void setup() override; void control(const std::string &value) override; + + protected: + // Convert log level to option index (skip CONFIG at level 4) + static uint8_t level_to_index(uint8_t level) { return (level > ESPHOME_LOG_LEVEL_CONFIG) ? level - 1 : level; } + // Convert option index to log level (skip CONFIG at level 4) + static uint8_t index_to_level(uint8_t index) { return (index >= ESPHOME_LOG_LEVEL_CONFIG) ? index + 1 : index; } }; } // namespace esphome::logger From d43b844e06b0a01f6ef0c550d7c95108fd09cbdf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 14:28:58 -0500 Subject: [PATCH 7/8] Bump ruff from 0.13.2 to 0.13.3 (#11000) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston --- .pre-commit-config.yaml | 2 +- requirements_test.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 818f360860..3c1b888cfd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ ci: repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.13.2 + rev: v0.13.3 hooks: # Run the linter. - id: ruff diff --git a/requirements_test.txt b/requirements_test.txt index 59ea77fd2d..f2be6f3a24 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,6 +1,6 @@ pylint==3.3.8 flake8==7.3.0 # also change in .pre-commit-config.yaml when updating -ruff==0.13.2 # also change in .pre-commit-config.yaml when updating +ruff==0.13.3 # also change in .pre-commit-config.yaml when updating pyupgrade==3.20.0 # also change in .pre-commit-config.yaml when updating pre-commit From 28324adfb9d03ced7b1f0696d2cb0c3d1eda3f13 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 3 Oct 2025 16:03:30 -0500 Subject: [PATCH 8/8] [logger] Conditionally compile runtime tag-specific log levels for performance --- esphome/components/logger/__init__.py | 11 +++++++++-- esphome/components/logger/logger.cpp | 10 ++++++++-- esphome/components/logger/logger.h | 15 +++++++++++++-- esphome/core/defines.h | 1 + tests/components/logger/common-default_uart.yaml | 5 +++++ 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/esphome/components/logger/__init__.py b/esphome/components/logger/__init__.py index 7d1a591f0c..1d02073d27 100644 --- a/esphome/components/logger/__init__.py +++ b/esphome/components/logger/__init__.py @@ -95,6 +95,7 @@ DEFAULT = "DEFAULT" CONF_INITIAL_LEVEL = "initial_level" CONF_LOGGER_ID = "logger_id" +CONF_RUNTIME_TAG_LEVELS = "runtime_tag_levels" CONF_TASK_LOG_BUFFER_SIZE = "task_log_buffer_size" UART_SELECTION_ESP32 = { @@ -249,6 +250,7 @@ CONFIG_SCHEMA = cv.All( } ), cv.Optional(CONF_INITIAL_LEVEL): is_log_level, + cv.Optional(CONF_RUNTIME_TAG_LEVELS, default=False): cv.boolean, cv.Optional(CONF_ON_MESSAGE): automation.validate_automation( { cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LoggerMessageTrigger), @@ -291,8 +293,12 @@ async def to_code(config): ) cg.add(log.pre_setup()) - for tag, log_level in config[CONF_LOGS].items(): - cg.add(log.set_log_level(tag, LOG_LEVELS[log_level])) + # Enable runtime tag levels if logs are configured or explicitly enabled + logs_config = config[CONF_LOGS] + if logs_config or config[CONF_RUNTIME_TAG_LEVELS]: + cg.add_define("USE_LOGGER_RUNTIME_TAG_LEVELS") + for tag, log_level in logs_config.items(): + cg.add(log.set_log_level(tag, LOG_LEVELS[log_level])) cg.add_define("USE_LOGGER") this_severity = LOG_LEVEL_SEVERITY.index(level) @@ -443,6 +449,7 @@ async def logger_set_level_to_code(config, action_id, template_arg, args): level = LOG_LEVELS[config[CONF_LEVEL]] logger = await cg.get_variable(config[CONF_LOGGER_ID]) if tag := config.get(CONF_TAG): + cg.add_define("USE_LOGGER_RUNTIME_TAG_LEVELS") text = str(cg.statement(logger.set_log_level(tag, level))) else: text = str(cg.statement(logger.set_log_level(level))) diff --git a/esphome/components/logger/logger.cpp b/esphome/components/logger/logger.cpp index 4a69bd9853..9a9bf89fe3 100644 --- a/esphome/components/logger/logger.cpp +++ b/esphome/components/logger/logger.cpp @@ -148,9 +148,11 @@ void Logger::log_vprintf_(uint8_t level, const char *tag, int line, const __Flas #endif // USE_STORE_LOG_STR_IN_FLASH inline uint8_t Logger::level_for(const char *tag) { +#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS auto it = this->log_levels_.find(tag); if (it != this->log_levels_.end()) return it->second; +#endif return this->current_level_; } @@ -220,7 +222,9 @@ void Logger::process_messages_() { } void Logger::set_baud_rate(uint32_t baud_rate) { this->baud_rate_ = baud_rate; } -void Logger::set_log_level(const std::string &tag, uint8_t log_level) { this->log_levels_[tag] = log_level; } +#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS +void Logger::set_log_level(const char *tag, uint8_t log_level) { this->log_levels_[tag] = log_level; } +#endif #if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR) UARTSelection Logger::get_uart() const { return this->uart_; } @@ -271,9 +275,11 @@ void Logger::dump_config() { } #endif +#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS for (auto &it : this->log_levels_) { - ESP_LOGCONFIG(TAG, " Level for '%s': %s", it.first.c_str(), LOG_STR_ARG(LOG_LEVELS[it.second])); + ESP_LOGCONFIG(TAG, " Level for '%s': %s", it.first, LOG_STR_ARG(LOG_LEVELS[it.second])); } +#endif } void Logger::set_log_level(uint8_t level) { diff --git a/esphome/components/logger/logger.h b/esphome/components/logger/logger.h index 7d4c14df0b..55fcfad9d0 100644 --- a/esphome/components/logger/logger.h +++ b/esphome/components/logger/logger.h @@ -36,6 +36,13 @@ struct device; namespace esphome::logger { +#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS +// Comparison function for const char* keys in log_levels_ map +struct CStrCompare { + bool operator()(const char *a, const char *b) const { return strcmp(a, b) < 0; } +}; +#endif + // ANSI color code last digit (30-38 range, store only last digit to save RAM) static constexpr char LOG_LEVEL_COLOR_DIGIT[] = { '\0', // NONE @@ -133,8 +140,10 @@ class Logger : public Component { /// Set the default log level for this logger. void set_log_level(uint8_t level); +#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS /// Set the log level of the specified tag. - void set_log_level(const std::string &tag, uint8_t log_level); + void set_log_level(const char *tag, uint8_t log_level); +#endif uint8_t get_log_level() { return this->current_level_; } // ========== INTERNAL METHODS ========== @@ -242,7 +251,9 @@ class Logger : public Component { #endif // Large objects (internally aligned) - std::map log_levels_{}; +#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS + std::map log_levels_{}; +#endif CallbackManager log_callback_{}; CallbackManager level_callback_{}; #ifdef USE_ESPHOME_TASK_LOG_BUFFER diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 7fc42ea334..fb8c217016 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -48,6 +48,7 @@ #define USE_LIGHT #define USE_LOCK #define USE_LOGGER +#define USE_LOGGER_RUNTIME_TAG_LEVELS #define USE_LVGL #define USE_LVGL_ANIMIMG #define USE_LVGL_ARC diff --git a/tests/components/logger/common-default_uart.yaml b/tests/components/logger/common-default_uart.yaml index e8b56043eb..7939a5f9c5 100644 --- a/tests/components/logger/common-default_uart.yaml +++ b/tests/components/logger/common-default_uart.yaml @@ -6,11 +6,16 @@ esphome: format: "Warning: Logger level is %d" args: [id(logger_id).get_log_level()] - logger.set_level: WARN + - logger.set_level: + level: ERROR + tag: mqtt.client logger: id: logger_id level: DEBUG initial_level: INFO + logs: + mqtt.component: WARN select: - platform: logger