mirror of
https://github.com/esphome/esphome.git
synced 2025-10-13 15:23:49 +01:00
Merge remote-tracking branch 'upstream/dev' into bound_tx_buf
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -466,7 +466,7 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
cache-key: ${{ needs.common.outputs.cache-key }}
|
||||
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
|
||||
- uses: esphome/action@43cd1109c09c544d97196f7730ee5b2e0cc6d81e # v3.0.1 fork with pinned actions/cache
|
||||
env:
|
||||
SKIP: pylint,clang-tidy-hash
|
||||
- uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0
|
||||
|
4
.github/workflows/codeql.yml
vendored
4
.github/workflows/codeql.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
|
||||
uses: github/codeql-action/init@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
@@ -86,6 +86,6 @@ jobs:
|
||||
exit 1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
|
||||
uses: github/codeql-action/analyze@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -14,6 +14,7 @@ from esphome.const import (
|
||||
CONF_EVENT,
|
||||
CONF_ID,
|
||||
CONF_KEY,
|
||||
CONF_MAX_CONNECTIONS,
|
||||
CONF_ON_CLIENT_CONNECTED,
|
||||
CONF_ON_CLIENT_DISCONNECTED,
|
||||
CONF_PASSWORD,
|
||||
@@ -60,7 +61,6 @@ CONF_CUSTOM_SERVICES = "custom_services"
|
||||
CONF_HOMEASSISTANT_SERVICES = "homeassistant_services"
|
||||
CONF_HOMEASSISTANT_STATES = "homeassistant_states"
|
||||
CONF_LISTEN_BACKLOG = "listen_backlog"
|
||||
CONF_MAX_CONNECTIONS = "max_connections"
|
||||
CONF_MAX_SEND_QUEUE = "max_send_queue"
|
||||
|
||||
|
||||
|
@@ -205,7 +205,8 @@ void APIConnection::loop() {
|
||||
// Disconnect if not responded within 2.5*keepalive
|
||||
if (now - this->last_traffic_ > KEEPALIVE_DISCONNECT_TIMEOUT) {
|
||||
on_fatal_error();
|
||||
ESP_LOGW(TAG, "%s is unresponsive; disconnecting", this->get_client_combined_info().c_str());
|
||||
ESP_LOGW(TAG, "%s (%s) is unresponsive; disconnecting", this->client_info_.name.c_str(),
|
||||
this->client_info_.peername.c_str());
|
||||
}
|
||||
} else if (now - this->last_traffic_ > KEEPALIVE_TIMEOUT_MS && !this->flags_.remove) {
|
||||
// Only send ping if we're not disconnecting
|
||||
@@ -255,7 +256,7 @@ bool APIConnection::send_disconnect_response(const DisconnectRequest &msg) {
|
||||
// remote initiated disconnect_client
|
||||
// don't close yet, we still need to send the disconnect response
|
||||
// close will happen on next loop
|
||||
ESP_LOGD(TAG, "%s disconnected", this->get_client_combined_info().c_str());
|
||||
ESP_LOGD(TAG, "%s (%s) disconnected", this->client_info_.name.c_str(), this->client_info_.peername.c_str());
|
||||
this->flags_.next_close = true;
|
||||
DisconnectResponse resp;
|
||||
return this->send_message(resp, DisconnectResponse::MESSAGE_TYPE);
|
||||
@@ -1385,7 +1386,7 @@ void APIConnection::complete_authentication_() {
|
||||
}
|
||||
|
||||
this->flags_.connection_state = static_cast<uint8_t>(ConnectionState::AUTHENTICATED);
|
||||
ESP_LOGD(TAG, "%s connected", this->get_client_combined_info().c_str());
|
||||
ESP_LOGD(TAG, "%s (%s) connected", this->client_info_.name.c_str(), this->client_info_.peername.c_str());
|
||||
#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
|
||||
this->parent_->get_client_connected_trigger()->trigger(this->client_info_.name, this->client_info_.peername);
|
||||
#endif
|
||||
@@ -1609,12 +1610,12 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
|
||||
#ifdef USE_API_PASSWORD
|
||||
void APIConnection::on_unauthenticated_access() {
|
||||
this->on_fatal_error();
|
||||
ESP_LOGD(TAG, "%s access without authentication", this->get_client_combined_info().c_str());
|
||||
ESP_LOGD(TAG, "%s (%s) no authentication", this->client_info_.name.c_str(), this->client_info_.peername.c_str());
|
||||
}
|
||||
#endif
|
||||
void APIConnection::on_no_setup_connection() {
|
||||
this->on_fatal_error();
|
||||
ESP_LOGD(TAG, "%s access without full connection", this->get_client_combined_info().c_str());
|
||||
ESP_LOGD(TAG, "%s (%s) no connection setup", this->client_info_.name.c_str(), this->client_info_.peername.c_str());
|
||||
}
|
||||
void APIConnection::on_fatal_error() {
|
||||
this->helper_->close();
|
||||
@@ -1866,8 +1867,8 @@ void APIConnection::process_state_subscriptions_() {
|
||||
#endif // USE_API_HOMEASSISTANT_STATES
|
||||
|
||||
void APIConnection::log_warning_(const LogString *message, APIError err) {
|
||||
ESP_LOGW(TAG, "%s: %s %s errno=%d", this->get_client_combined_info().c_str(), LOG_STR_ARG(message),
|
||||
LOG_STR_ARG(api_error_to_logstr(err)), errno);
|
||||
ESP_LOGW(TAG, "%s (%s): %s %s errno=%d", this->client_info_.name.c_str(), this->client_info_.peername.c_str(),
|
||||
LOG_STR_ARG(message), LOG_STR_ARG(api_error_to_logstr(err)), errno);
|
||||
}
|
||||
|
||||
void APIConnection::log_socket_operation_failed_(APIError err) {
|
||||
|
@@ -19,14 +19,6 @@ namespace esphome::api {
|
||||
struct ClientInfo {
|
||||
std::string name; // Client name from Hello message
|
||||
std::string peername; // IP:port from socket
|
||||
|
||||
std::string get_combined_info() const {
|
||||
if (name == peername) {
|
||||
// Before Hello message, both are the same
|
||||
return name;
|
||||
}
|
||||
return name + " (" + peername + ")";
|
||||
}
|
||||
};
|
||||
|
||||
// Keepalive timeout in milliseconds
|
||||
@@ -278,7 +270,8 @@ class APIConnection final : public APIServerConnection {
|
||||
bool try_to_clear_buffer(bool log_out_of_space);
|
||||
bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) override;
|
||||
|
||||
std::string get_client_combined_info() const { return this->client_info_.get_combined_info(); }
|
||||
const std::string &get_name() const { return this->client_info_.name; }
|
||||
const std::string &get_peername() const { return this->client_info_.peername; }
|
||||
|
||||
protected:
|
||||
// Helper function to handle authentication completion
|
||||
|
@@ -13,7 +13,8 @@ namespace esphome::api {
|
||||
|
||||
static const char *const TAG = "api.frame_helper";
|
||||
|
||||
#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
|
||||
#define HELPER_LOG(msg, ...) \
|
||||
ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
|
||||
|
||||
#ifdef HELPER_LOG_PACKETS
|
||||
#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
|
||||
|
@@ -24,7 +24,8 @@ static const char *const PROLOGUE_INIT = "NoiseAPIInit";
|
||||
#endif
|
||||
static constexpr size_t PROLOGUE_INIT_LEN = 12; // strlen("NoiseAPIInit")
|
||||
|
||||
#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
|
||||
#define HELPER_LOG(msg, ...) \
|
||||
ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
|
||||
|
||||
#ifdef HELPER_LOG_PACKETS
|
||||
#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
|
||||
|
@@ -18,7 +18,8 @@ namespace esphome::api {
|
||||
|
||||
static const char *const TAG = "api.plaintext";
|
||||
|
||||
#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
|
||||
#define HELPER_LOG(msg, ...) \
|
||||
ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
|
||||
|
||||
#ifdef HELPER_LOG_PACKETS
|
||||
#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
|
||||
|
@@ -177,7 +177,8 @@ void APIServer::loop() {
|
||||
// Network is down - disconnect all clients
|
||||
for (auto &client : this->clients_) {
|
||||
client->on_fatal_error();
|
||||
ESP_LOGW(TAG, "%s: Network down; disconnect", client->get_client_combined_info().c_str());
|
||||
ESP_LOGW(TAG, "%s (%s): Network down; disconnect", client->client_info_.name.c_str(),
|
||||
client->client_info_.peername.c_str());
|
||||
}
|
||||
// Continue to process and clean up the clients below
|
||||
}
|
||||
|
@@ -55,7 +55,7 @@ template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
|
||||
|
||||
protected:
|
||||
virtual void execute(Ts... x) = 0;
|
||||
template<int... S> void execute_(std::vector<ExecuteServiceArgument> args, seq<S...> type) {
|
||||
template<int... S> void execute_(const std::vector<ExecuteServiceArgument> &args, seq<S...> type) {
|
||||
this->execute((get_execute_arg_value<Ts>(args[S]))...);
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,7 @@ from esphome.const import (
|
||||
CONF_INTERVAL,
|
||||
CONF_MAC_ADDRESS,
|
||||
CONF_MANUFACTURER_ID,
|
||||
CONF_MAX_CONNECTIONS,
|
||||
CONF_ON_BLE_ADVERTISE,
|
||||
CONF_ON_BLE_MANUFACTURER_DATA_ADVERTISE,
|
||||
CONF_ON_BLE_SERVICE_DATA_ADVERTISE,
|
||||
@@ -41,7 +42,6 @@ CODEOWNERS = ["@bdraco"]
|
||||
KEY_ESP32_BLE_TRACKER = "esp32_ble_tracker"
|
||||
KEY_USED_CONNECTION_SLOTS = "used_connection_slots"
|
||||
|
||||
CONF_MAX_CONNECTIONS = "max_connections"
|
||||
CONF_ESP32_BLE_ID = "esp32_ble_id"
|
||||
CONF_SCAN_PARAMETERS = "scan_parameters"
|
||||
CONF_WINDOW = "window"
|
||||
|
@@ -67,8 +67,16 @@ static bool get_bitrate(canbus::CanSpeed bitrate, twai_timing_config_t *t_config
|
||||
}
|
||||
|
||||
bool ESP32Can::setup_internal() {
|
||||
static int next_twai_ctrl_num = 0;
|
||||
if (next_twai_ctrl_num >= SOC_TWAI_CONTROLLER_NUM) {
|
||||
ESP_LOGW(TAG, "Maximum number of esp32_can components created already");
|
||||
this->mark_failed();
|
||||
return false;
|
||||
}
|
||||
|
||||
twai_general_config_t g_config =
|
||||
TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t) this->tx_, (gpio_num_t) this->rx_, TWAI_MODE_NORMAL);
|
||||
g_config.controller_id = next_twai_ctrl_num++;
|
||||
if (this->tx_queue_len_.has_value()) {
|
||||
g_config.tx_queue_len = this->tx_queue_len_.value();
|
||||
}
|
||||
@@ -86,14 +94,14 @@ bool ESP32Can::setup_internal() {
|
||||
}
|
||||
|
||||
// Install TWAI driver
|
||||
if (twai_driver_install(&g_config, &t_config, &f_config) != ESP_OK) {
|
||||
if (twai_driver_install_v2(&g_config, &t_config, &f_config, &(this->twai_handle_)) != ESP_OK) {
|
||||
// Failed to install driver
|
||||
this->mark_failed();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start TWAI driver
|
||||
if (twai_start() != ESP_OK) {
|
||||
if (twai_start_v2(this->twai_handle_) != ESP_OK) {
|
||||
// Failed to start driver
|
||||
this->mark_failed();
|
||||
return false;
|
||||
@@ -102,6 +110,11 @@ bool ESP32Can::setup_internal() {
|
||||
}
|
||||
|
||||
canbus::Error ESP32Can::send_message(struct canbus::CanFrame *frame) {
|
||||
if (this->twai_handle_ == nullptr) {
|
||||
// not setup yet or setup failed
|
||||
return canbus::ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (frame->can_data_length_code > canbus::CAN_MAX_DATA_LENGTH) {
|
||||
return canbus::ERROR_FAILTX;
|
||||
}
|
||||
@@ -124,7 +137,7 @@ canbus::Error ESP32Can::send_message(struct canbus::CanFrame *frame) {
|
||||
memcpy(message.data, frame->data, frame->can_data_length_code);
|
||||
}
|
||||
|
||||
if (twai_transmit(&message, this->tx_enqueue_timeout_ticks_) == ESP_OK) {
|
||||
if (twai_transmit_v2(this->twai_handle_, &message, this->tx_enqueue_timeout_ticks_) == ESP_OK) {
|
||||
return canbus::ERROR_OK;
|
||||
} else {
|
||||
return canbus::ERROR_ALLTXBUSY;
|
||||
@@ -132,9 +145,14 @@ canbus::Error ESP32Can::send_message(struct canbus::CanFrame *frame) {
|
||||
}
|
||||
|
||||
canbus::Error ESP32Can::read_message(struct canbus::CanFrame *frame) {
|
||||
if (this->twai_handle_ == nullptr) {
|
||||
// not setup yet or setup failed
|
||||
return canbus::ERROR_FAIL;
|
||||
}
|
||||
|
||||
twai_message_t message;
|
||||
|
||||
if (twai_receive(&message, 0) != ESP_OK) {
|
||||
if (twai_receive_v2(this->twai_handle_, &message, 0) != ESP_OK) {
|
||||
return canbus::ERROR_NOMSG;
|
||||
}
|
||||
|
||||
|
@@ -5,6 +5,8 @@
|
||||
#include "esphome/components/canbus/canbus.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
#include <driver/twai.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace esp32_can {
|
||||
|
||||
@@ -29,6 +31,7 @@ class ESP32Can : public canbus::Canbus {
|
||||
TickType_t tx_enqueue_timeout_ticks_{};
|
||||
optional<uint32_t> tx_queue_len_{};
|
||||
optional<uint32_t> rx_queue_len_{};
|
||||
twai_handle_t twai_handle_{nullptr};
|
||||
};
|
||||
|
||||
} // namespace esp32_can
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -13,13 +13,12 @@ static const char *const TAG = "mpr121";
|
||||
void MPR121Component::setup() {
|
||||
// soft reset device
|
||||
this->write_byte(MPR121_SOFTRESET, 0x63);
|
||||
delay(100); // NOLINT
|
||||
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();
|
||||
@@ -52,6 +51,8 @@ void MPR121Component::setup() {
|
||||
this->write_byte(MPR121_ECR, 0x80 | (this->max_touch_channel_ + 1));
|
||||
|
||||
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);
|
||||
|
||||
|
@@ -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_();
|
||||
|
@@ -374,7 +374,7 @@ void Rtttl::loop() {
|
||||
this->last_note_ = millis();
|
||||
}
|
||||
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
||||
static const LogString *state_to_string(State state) {
|
||||
switch (state) {
|
||||
case STATE_STOPPED:
|
||||
|
@@ -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);
|
||||
this->result_ = this->write_command(SPS30_CMD_SET_AUTOMATIC_CLEANING_INTERVAL_SECONDS);
|
||||
}
|
||||
if (result) {
|
||||
delay(20);
|
||||
|
||||
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");
|
||||
|
@@ -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 {
|
||||
|
@@ -429,8 +429,9 @@ void VoiceAssistant::client_subscription(api::APIConnection *client, bool subscr
|
||||
|
||||
if (this->api_client_ != nullptr) {
|
||||
ESP_LOGE(TAG, "Multiple API Clients attempting to connect to Voice Assistant");
|
||||
ESP_LOGE(TAG, "Current client: %s", this->api_client_->get_client_combined_info().c_str());
|
||||
ESP_LOGE(TAG, "New client: %s", client->get_client_combined_info().c_str());
|
||||
ESP_LOGE(TAG, "Current client: %s (%s)", this->api_client_->get_name().c_str(),
|
||||
this->api_client_->get_peername().c_str());
|
||||
ESP_LOGE(TAG, "New client: %s (%s)", client->get_name().c_str(), client->get_peername().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -542,6 +542,7 @@ CONF_MANUAL_IP = "manual_ip"
|
||||
CONF_MANUFACTURER_ID = "manufacturer_id"
|
||||
CONF_MASK_DISTURBER = "mask_disturber"
|
||||
CONF_MAX_BRIGHTNESS = "max_brightness"
|
||||
CONF_MAX_CONNECTIONS = "max_connections"
|
||||
CONF_MAX_COOLING_RUN_TIME = "max_cooling_run_time"
|
||||
CONF_MAX_CURRENT = "max_current"
|
||||
CONF_MAX_DURATION = "max_duration"
|
||||
@@ -1169,7 +1170,7 @@ UNIT_KILOMETER = "km"
|
||||
UNIT_KILOMETER_PER_HOUR = "km/h"
|
||||
UNIT_KILOVOLT_AMPS = "kVA"
|
||||
UNIT_KILOVOLT_AMPS_HOURS = "kVAh"
|
||||
UNIT_KILOVOLT_AMPS_REACTIVE = "kVAR"
|
||||
UNIT_KILOVOLT_AMPS_REACTIVE = "kvar"
|
||||
UNIT_KILOVOLT_AMPS_REACTIVE_HOURS = "kvarh"
|
||||
UNIT_KILOWATT = "kW"
|
||||
UNIT_KILOWATT_HOURS = "kWh"
|
||||
|
@@ -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
|
||||
|
||||
|
89
tests/components/esp32_can/test.esp32-c6-idf.yaml
Normal file
89
tests/components/esp32_can/test.esp32-c6-idf.yaml
Normal file
@@ -0,0 +1,89 @@
|
||||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- canbus.send:
|
||||
# Extended ID explicit
|
||||
canbus_id: esp32_internal_can
|
||||
use_extended_id: true
|
||||
can_id: 0x100
|
||||
data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]
|
||||
- canbus.send:
|
||||
# Standard ID by default
|
||||
canbus_id: esp32_internal_can
|
||||
can_id: 0x100
|
||||
data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]
|
||||
- canbus.send:
|
||||
# Extended ID explicit
|
||||
canbus_id: esp32_internal_can_2
|
||||
use_extended_id: true
|
||||
can_id: 0x100
|
||||
data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]
|
||||
- canbus.send:
|
||||
# Standard ID by default
|
||||
canbus_id: esp32_internal_can_2
|
||||
can_id: 0x100
|
||||
data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]
|
||||
|
||||
canbus:
|
||||
- platform: esp32_can
|
||||
id: esp32_internal_can
|
||||
rx_pin: GPIO8
|
||||
tx_pin: GPIO7
|
||||
can_id: 4
|
||||
bit_rate: 50kbps
|
||||
on_frame:
|
||||
- can_id: 500
|
||||
then:
|
||||
- lambda: |-
|
||||
std::string b(x.begin(), x.end());
|
||||
ESP_LOGD("canbus1", "canid 500 %s", b.c_str() );
|
||||
- can_id: 0b00000000000000000000001000000
|
||||
can_id_mask: 0b11111000000000011111111000000
|
||||
use_extended_id: true
|
||||
then:
|
||||
- lambda: |-
|
||||
auto pdo_id = can_id >> 14;
|
||||
switch (pdo_id)
|
||||
{
|
||||
case 117:
|
||||
ESP_LOGD("canbus1", "exhaust_fan_duty");
|
||||
break;
|
||||
case 118:
|
||||
ESP_LOGD("canbus1", "supply_fan_duty");
|
||||
break;
|
||||
case 119:
|
||||
ESP_LOGD("canbus1", "supply_fan_flow");
|
||||
break;
|
||||
// to be continued...
|
||||
}
|
||||
- platform: esp32_can
|
||||
id: esp32_internal_can_2
|
||||
rx_pin: GPIO10
|
||||
tx_pin: GPIO9
|
||||
can_id: 4
|
||||
bit_rate: 50kbps
|
||||
on_frame:
|
||||
- can_id: 500
|
||||
then:
|
||||
- lambda: |-
|
||||
std::string b(x.begin(), x.end());
|
||||
ESP_LOGD("canbus2", "canid 500 %s", b.c_str() );
|
||||
- can_id: 0b00000000000000000000001000000
|
||||
can_id_mask: 0b11111000000000011111111000000
|
||||
use_extended_id: true
|
||||
then:
|
||||
- lambda: |-
|
||||
auto pdo_id = can_id >> 14;
|
||||
switch (pdo_id)
|
||||
{
|
||||
case 117:
|
||||
ESP_LOGD("canbus2", "exhaust_fan_duty");
|
||||
break;
|
||||
case 118:
|
||||
ESP_LOGD("canbus2", "supply_fan_duty");
|
||||
break;
|
||||
case 119:
|
||||
ESP_LOGD("canbus2", "supply_fan_flow");
|
||||
break;
|
||||
// to be continued...
|
||||
}
|
Reference in New Issue
Block a user