1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-06 20:03:46 +01:00

Merge branch 'dev' into use_idf_webserver_esp32

This commit is contained in:
J. Nick Koston
2025-10-03 16:42:21 -05:00
committed by GitHub
11 changed files with 92 additions and 65 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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<Logger> {
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

View File

@@ -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);

View File

@@ -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<MPR121Channel *> 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_();

View File

@@ -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");

View File

@@ -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 {

View File

@@ -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