mirror of
https://github.com/esphome/esphome.git
synced 2026-09-20 03:28:41 +00:00
Merge branch 'dev' into ota-use-idf-backend-for-all-esp32
This commit is contained in:
@@ -11,7 +11,7 @@ ci:
|
||||
repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.14.5
|
||||
rev: v0.14.7
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
|
||||
@@ -21,6 +21,7 @@ esphome/components/adc128s102/* @DeerMaximum
|
||||
esphome/components/addressable_light/* @justfalter
|
||||
esphome/components/ade7880/* @kpfleming
|
||||
esphome/components/ade7953/* @angelnu
|
||||
esphome/components/ade7953_base/* @angelnu
|
||||
esphome/components/ade7953_i2c/* @angelnu
|
||||
esphome/components/ade7953_spi/* @angelnu
|
||||
esphome/components/ads1118/* @solomondg1
|
||||
|
||||
@@ -24,6 +24,8 @@ from esphome.const import (
|
||||
UNIT_WATT,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@angelnu"]
|
||||
|
||||
CONF_CURRENT_A = "current_a"
|
||||
CONF_CURRENT_B = "current_b"
|
||||
CONF_ACTIVE_POWER_A = "active_power_a"
|
||||
|
||||
@@ -25,7 +25,8 @@ void ADE7953::setup() {
|
||||
this->ade_write_8(PGA_V_8, pga_v_);
|
||||
this->ade_write_8(PGA_IA_8, pga_ia_);
|
||||
this->ade_write_8(PGA_IB_8, pga_ib_);
|
||||
this->ade_write_32(AVGAIN_32, vgain_);
|
||||
this->ade_write_32(AVGAIN_32, avgain_);
|
||||
this->ade_write_32(BVGAIN_32, bvgain_);
|
||||
this->ade_write_32(AIGAIN_32, aigain_);
|
||||
this->ade_write_32(BIGAIN_32, bigain_);
|
||||
this->ade_write_32(AWGAIN_32, awgain_);
|
||||
@@ -34,7 +35,8 @@ void ADE7953::setup() {
|
||||
this->ade_read_8(PGA_V_8, &pga_v_);
|
||||
this->ade_read_8(PGA_IA_8, &pga_ia_);
|
||||
this->ade_read_8(PGA_IB_8, &pga_ib_);
|
||||
this->ade_read_32(AVGAIN_32, &vgain_);
|
||||
this->ade_read_32(AVGAIN_32, &avgain_);
|
||||
this->ade_read_32(BVGAIN_32, &bvgain_);
|
||||
this->ade_read_32(AIGAIN_32, &aigain_);
|
||||
this->ade_read_32(BIGAIN_32, &bigain_);
|
||||
this->ade_read_32(AWGAIN_32, &awgain_);
|
||||
@@ -63,13 +65,14 @@ void ADE7953::dump_config() {
|
||||
" PGA_V_8: 0x%X\n"
|
||||
" PGA_IA_8: 0x%X\n"
|
||||
" PGA_IB_8: 0x%X\n"
|
||||
" VGAIN_32: 0x%08jX\n"
|
||||
" AVGAIN_32: 0x%08jX\n"
|
||||
" BVGAIN_32: 0x%08jX\n"
|
||||
" AIGAIN_32: 0x%08jX\n"
|
||||
" BIGAIN_32: 0x%08jX\n"
|
||||
" AWGAIN_32: 0x%08jX\n"
|
||||
" BWGAIN_32: 0x%08jX",
|
||||
this->use_acc_energy_regs_, pga_v_, pga_ia_, pga_ib_, (uintmax_t) vgain_, (uintmax_t) aigain_,
|
||||
(uintmax_t) bigain_, (uintmax_t) awgain_, (uintmax_t) bwgain_);
|
||||
this->use_acc_energy_regs_, pga_v_, pga_ia_, pga_ib_, (uintmax_t) avgain_, (uintmax_t) bvgain_,
|
||||
(uintmax_t) aigain_, (uintmax_t) bigain_, (uintmax_t) awgain_, (uintmax_t) bwgain_);
|
||||
}
|
||||
|
||||
#define ADE_PUBLISH_(name, val, factor) \
|
||||
|
||||
@@ -46,7 +46,12 @@ class ADE7953 : public PollingComponent, public sensor::Sensor {
|
||||
void set_pga_ib(uint8_t pga_ib) { pga_ib_ = pga_ib; }
|
||||
|
||||
// Set input gains
|
||||
void set_vgain(uint32_t vgain) { vgain_ = vgain; }
|
||||
void set_vgain(uint32_t vgain) {
|
||||
// Datasheet says: "to avoid discrepancies in other registers,
|
||||
// if AVGAIN is set then BVGAIN should be set to the same value."
|
||||
avgain_ = vgain;
|
||||
bvgain_ = vgain;
|
||||
}
|
||||
void set_aigain(uint32_t aigain) { aigain_ = aigain; }
|
||||
void set_bigain(uint32_t bigain) { bigain_ = bigain; }
|
||||
void set_awgain(uint32_t awgain) { awgain_ = awgain; }
|
||||
@@ -100,7 +105,8 @@ class ADE7953 : public PollingComponent, public sensor::Sensor {
|
||||
uint8_t pga_v_;
|
||||
uint8_t pga_ia_;
|
||||
uint8_t pga_ib_;
|
||||
uint32_t vgain_;
|
||||
uint32_t avgain_;
|
||||
uint32_t bvgain_;
|
||||
uint32_t aigain_;
|
||||
uint32_t bigain_;
|
||||
uint32_t awgain_;
|
||||
|
||||
@@ -589,6 +589,7 @@ enum SensorStateClass {
|
||||
STATE_CLASS_MEASUREMENT = 1;
|
||||
STATE_CLASS_TOTAL_INCREASING = 2;
|
||||
STATE_CLASS_TOTAL = 3;
|
||||
STATE_CLASS_MEASUREMENT_ANGLE = 4;
|
||||
}
|
||||
|
||||
// Deprecated in API version 1.5
|
||||
|
||||
@@ -169,8 +169,7 @@ void APIConnection::loop() {
|
||||
} else {
|
||||
this->last_traffic_ = now;
|
||||
// read a packet
|
||||
this->read_message(buffer.data_len, buffer.type,
|
||||
buffer.data_len > 0 ? &buffer.container[buffer.data_offset] : nullptr);
|
||||
this->read_message(buffer.data_len, buffer.type, buffer.data);
|
||||
if (this->flags_.remove)
|
||||
return;
|
||||
}
|
||||
@@ -195,6 +194,9 @@ void APIConnection::loop() {
|
||||
}
|
||||
// Now that everything is sent, enable immediate sending for future state changes
|
||||
this->flags_.should_try_send_immediately = true;
|
||||
// Release excess memory from buffers that grew during initial sync
|
||||
this->deferred_batch_.release_buffer();
|
||||
this->helper_->release_buffers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -554,10 +554,8 @@ class APIConnection final : public APIServerConnection {
|
||||
std::vector<BatchItem> items;
|
||||
uint32_t batch_start_time{0};
|
||||
|
||||
DeferredBatch() {
|
||||
// Pre-allocate capacity for typical batch sizes to avoid reallocation
|
||||
items.reserve(8);
|
||||
}
|
||||
// No pre-allocation - log connections never use batching, and for
|
||||
// connections that do, buffers are released after initial sync anyway
|
||||
|
||||
// Add item to the batch
|
||||
void add_item(EntityBase *entity, MessageCreator creator, uint8_t message_type, uint8_t estimated_size);
|
||||
@@ -576,6 +574,15 @@ class APIConnection final : public APIServerConnection {
|
||||
bool empty() const { return items.empty(); }
|
||||
size_t size() const { return items.size(); }
|
||||
const BatchItem &operator[](size_t index) const { return items[index]; }
|
||||
// Release excess capacity - only releases if items already empty
|
||||
void release_buffer() {
|
||||
// Safe to call: batch is processed before release_buffer is called,
|
||||
// and if any items remain (partial processing), we must not clear them.
|
||||
// Use swap trick since shrink_to_fit() is non-binding and may be ignored.
|
||||
if (items.empty()) {
|
||||
std::vector<BatchItem>().swap(items);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// DeferredBatch here (16 bytes, 4-byte aligned)
|
||||
|
||||
@@ -35,10 +35,9 @@ struct ClientInfo;
|
||||
class ProtoWriteBuffer;
|
||||
|
||||
struct ReadPacketBuffer {
|
||||
std::vector<uint8_t> container;
|
||||
uint16_t type;
|
||||
uint16_t data_offset;
|
||||
const uint8_t *data; // Points directly into frame helper's rx_buf_ (valid until next read_packet call)
|
||||
uint16_t data_len;
|
||||
uint16_t type;
|
||||
};
|
||||
|
||||
// Packed packet info structure to minimize memory usage
|
||||
@@ -119,6 +118,22 @@ class APIFrameHelper {
|
||||
uint8_t frame_footer_size() const { return frame_footer_size_; }
|
||||
// Check if socket has data ready to read
|
||||
bool is_socket_ready() const { return socket_ != nullptr && socket_->ready(); }
|
||||
// Release excess memory from internal buffers after initial sync
|
||||
void release_buffers() {
|
||||
// rx_buf_: Safe to clear only if no partial read in progress.
|
||||
// rx_buf_len_ tracks bytes read so far; if non-zero, we're mid-frame
|
||||
// and clearing would lose partially received data.
|
||||
if (this->rx_buf_len_ == 0) {
|
||||
// Use swap trick since shrink_to_fit() is non-binding and may be ignored
|
||||
std::vector<uint8_t>().swap(this->rx_buf_);
|
||||
}
|
||||
// reusable_iovs_: Safe to release unconditionally.
|
||||
// Only used within write_protobuf_packets() calls - cleared at start,
|
||||
// populated with pointers, used for writev(), then function returns.
|
||||
// The iovecs contain stale pointers after the call (data was either sent
|
||||
// or copied to tx_buf_), and are cleared on next write_protobuf_packets().
|
||||
std::vector<struct iovec>().swap(this->reusable_iovs_);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Buffer containing data to be sent
|
||||
|
||||
@@ -407,8 +407,7 @@ APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) {
|
||||
return APIError::BAD_DATA_PACKET;
|
||||
}
|
||||
|
||||
buffer->container = std::move(this->rx_buf_);
|
||||
buffer->data_offset = 4;
|
||||
buffer->data = msg_data + 4; // Skip 4-byte header (type + length)
|
||||
buffer->data_len = data_len;
|
||||
buffer->type = type;
|
||||
return APIError::OK;
|
||||
|
||||
@@ -210,8 +210,7 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
|
||||
return aerr;
|
||||
}
|
||||
|
||||
buffer->container = std::move(this->rx_buf_);
|
||||
buffer->data_offset = 0;
|
||||
buffer->data = this->rx_buf_.data();
|
||||
buffer->data_len = this->rx_header_parsed_len_;
|
||||
buffer->type = this->rx_header_parsed_type_;
|
||||
return APIError::OK;
|
||||
|
||||
@@ -51,6 +51,7 @@ enum SensorStateClass : uint32_t {
|
||||
STATE_CLASS_MEASUREMENT = 1,
|
||||
STATE_CLASS_TOTAL_INCREASING = 2,
|
||||
STATE_CLASS_TOTAL = 3,
|
||||
STATE_CLASS_MEASUREMENT_ANGLE = 4,
|
||||
};
|
||||
#endif
|
||||
enum LogLevel : uint32_t {
|
||||
|
||||
@@ -179,6 +179,8 @@ template<> const char *proto_enum_to_string<enums::SensorStateClass>(enums::Sens
|
||||
return "STATE_CLASS_TOTAL_INCREASING";
|
||||
case enums::STATE_CLASS_TOTAL:
|
||||
return "STATE_CLASS_TOTAL";
|
||||
case enums::STATE_CLASS_MEASUREMENT_ANGLE:
|
||||
return "STATE_CLASS_MEASUREMENT_ANGLE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ void APIServerConnectionBase::log_send_message_(const char *name, const std::str
|
||||
}
|
||||
#endif
|
||||
|
||||
void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) {
|
||||
void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) {
|
||||
switch (msg_type) {
|
||||
case HelloRequest::MESSAGE_TYPE: {
|
||||
HelloRequest msg;
|
||||
@@ -827,7 +827,7 @@ void APIServerConnection::on_z_wave_proxy_frame(const ZWaveProxyFrame &msg) { th
|
||||
void APIServerConnection::on_z_wave_proxy_request(const ZWaveProxyRequest &msg) { this->zwave_proxy_request(msg); }
|
||||
#endif
|
||||
|
||||
void APIServerConnection::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) {
|
||||
void APIServerConnection::read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) {
|
||||
// Check authentication/connection requirements for messages
|
||||
switch (msg_type) {
|
||||
case HelloRequest::MESSAGE_TYPE: // No setup required
|
||||
|
||||
@@ -218,7 +218,7 @@ class APIServerConnectionBase : public ProtoService {
|
||||
virtual void on_z_wave_proxy_request(const ZWaveProxyRequest &value){};
|
||||
#endif
|
||||
protected:
|
||||
void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override;
|
||||
void read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) override;
|
||||
};
|
||||
|
||||
class APIServerConnection : public APIServerConnectionBase {
|
||||
@@ -480,7 +480,7 @@ class APIServerConnection : public APIServerConnectionBase {
|
||||
#ifdef USE_ZWAVE_PROXY
|
||||
void on_z_wave_proxy_request(const ZWaveProxyRequest &msg) override;
|
||||
#endif
|
||||
void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override;
|
||||
void read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::api
|
||||
|
||||
@@ -101,19 +101,7 @@ void APIServer::setup() {
|
||||
|
||||
#ifdef USE_LOGGER
|
||||
if (logger::global_logger != nullptr) {
|
||||
logger::global_logger->add_on_log_callback(
|
||||
[this](int level, const char *tag, const char *message, size_t message_len) {
|
||||
if (this->shutting_down_) {
|
||||
// Don't try to send logs during shutdown
|
||||
// as it could result in a recursion and
|
||||
// we would be filling a buffer we are trying to clear
|
||||
return;
|
||||
}
|
||||
for (auto &c : this->clients_) {
|
||||
if (!c->flags_.remove && c->get_log_subscription_level() >= level)
|
||||
c->try_send_log_message(level, tag, message, message_len);
|
||||
}
|
||||
});
|
||||
logger::global_logger->add_log_listener(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -541,6 +529,21 @@ bool APIServer::is_connected(bool state_subscription_only) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_LOGGER
|
||||
void APIServer::on_log(uint8_t level, const char *tag, const char *message, size_t message_len) {
|
||||
if (this->shutting_down_) {
|
||||
// Don't try to send logs during shutdown
|
||||
// as it could result in a recursion and
|
||||
// we would be filling a buffer we are trying to clear
|
||||
return;
|
||||
}
|
||||
for (auto &c : this->clients_) {
|
||||
if (!c->flags_.remove && c->get_log_subscription_level() >= level)
|
||||
c->try_send_log_message(level, tag, message, message_len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void APIServer::on_shutdown() {
|
||||
this->shutting_down_ = true;
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#ifdef USE_API_USER_DEFINED_ACTIONS
|
||||
#include "user_services.h"
|
||||
#endif
|
||||
#ifdef USE_LOGGER
|
||||
#include "esphome/components/logger/logger.h"
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
@@ -27,7 +30,13 @@ struct SavedNoisePsk {
|
||||
} PACKED; // NOLINT
|
||||
#endif
|
||||
|
||||
class APIServer : public Component, public Controller {
|
||||
class APIServer : public Component,
|
||||
public Controller
|
||||
#ifdef USE_LOGGER
|
||||
,
|
||||
public logger::LogListener
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
APIServer();
|
||||
void setup() override;
|
||||
@@ -37,6 +46,9 @@ class APIServer : public Component, public Controller {
|
||||
void dump_config() override;
|
||||
void on_shutdown() override;
|
||||
bool teardown() override;
|
||||
#ifdef USE_LOGGER
|
||||
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override;
|
||||
#endif
|
||||
#ifdef USE_API_PASSWORD
|
||||
bool check_password(const uint8_t *password_data, size_t password_len) const;
|
||||
void set_password(const std::string &password);
|
||||
|
||||
@@ -846,7 +846,7 @@ class ProtoService {
|
||||
*/
|
||||
virtual ProtoWriteBuffer create_buffer(uint32_t reserve_size) = 0;
|
||||
virtual bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) = 0;
|
||||
virtual void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) = 0;
|
||||
virtual void read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) = 0;
|
||||
|
||||
// Optimized method that pre-allocates buffer based on message size
|
||||
bool send_message_(const ProtoMessage &msg, uint8_t message_type) {
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
|
||||
#include "automation.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
const char *const Automation::TAG = "ble_client.automation";
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
#include "esphome/components/ble_client/ble_client.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
// placeholder class for static TAG .
|
||||
class Automation {
|
||||
@@ -391,7 +390,6 @@ template<typename... Ts> class BLEClientDisconnectAction : public Action<Ts...>,
|
||||
BLEClient *ble_client_;
|
||||
std::tuple<Ts...> var_{};
|
||||
};
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
static const char *const TAG = "ble_client";
|
||||
|
||||
@@ -82,7 +81,6 @@ bool BLEClient::all_nodes_established_() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
namespace espbt = esphome::esp32_ble_tracker;
|
||||
|
||||
@@ -75,7 +74,6 @@ class BLEClient : public BLEClientBase {
|
||||
std::vector<BLEClientNode *> nodes_;
|
||||
};
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"
|
||||
|
||||
#ifdef USE_ESP32
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
static const char *const TAG = "ble_binary_output";
|
||||
|
||||
@@ -75,6 +74,5 @@ void BLEBinaryOutput::write_state(bool state) {
|
||||
ESP_LOGW(TAG, "[%s] Write error, err=%d", this->char_uuid_.to_string().c_str(), err);
|
||||
}
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
#endif
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
|
||||
#ifdef USE_ESP32
|
||||
#include <esp_gattc_api.h>
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
namespace espbt = esphome::esp32_ble_tracker;
|
||||
|
||||
@@ -36,7 +35,6 @@ class BLEBinaryOutput : public output::BinaryOutput, public BLEClientNode, publi
|
||||
esp_gatt_write_type_t write_type_{};
|
||||
};
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
class BLESensorNotifyTrigger : public Trigger<float>, public BLESensor {
|
||||
public:
|
||||
@@ -35,7 +34,6 @@ class BLESensorNotifyTrigger : public Trigger<float>, public BLESensor {
|
||||
BLESensor *sensor_;
|
||||
};
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
static const char *const TAG = "ble_rssi_sensor";
|
||||
|
||||
@@ -78,6 +77,5 @@ void BLEClientRSSISensor::get_rssi_() {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
#endif
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
#ifdef USE_ESP32
|
||||
#include <esp_gattc_api.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
namespace espbt = esphome::esp32_ble_tracker;
|
||||
|
||||
@@ -29,6 +28,5 @@ class BLEClientRSSISensor : public sensor::Sensor, public PollingComponent, publ
|
||||
bool should_update_{false};
|
||||
};
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
#endif
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
static const char *const TAG = "ble_sensor";
|
||||
|
||||
@@ -147,6 +146,5 @@ void BLESensor::update() {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
#endif
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
#ifdef USE_ESP32
|
||||
#include <esp_gattc_api.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
namespace espbt = esphome::esp32_ble_tracker;
|
||||
|
||||
@@ -48,6 +47,5 @@ class BLESensor : public sensor::Sensor, public PollingComponent, public BLEClie
|
||||
espbt::ESPBTUUID descr_uuid_;
|
||||
};
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
#endif
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
static const char *const TAG = "ble_switch";
|
||||
|
||||
@@ -31,6 +30,5 @@ void BLEClientSwitch::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
|
||||
|
||||
void BLEClientSwitch::dump_config() { LOG_SWITCH("", "BLE Client Switch", this); }
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
#endif
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
#ifdef USE_ESP32
|
||||
#include <esp_gattc_api.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
namespace espbt = esphome::esp32_ble_tracker;
|
||||
|
||||
@@ -24,6 +23,5 @@ class BLEClientSwitch : public switch_::Switch, public Component, public BLEClie
|
||||
void write_state(bool state) override;
|
||||
};
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
#endif
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
class BLETextSensorNotifyTrigger : public Trigger<std::string>, public BLETextSensor {
|
||||
public:
|
||||
@@ -33,7 +32,6 @@ class BLETextSensorNotifyTrigger : public Trigger<std::string>, public BLETextSe
|
||||
BLETextSensor *sensor_;
|
||||
};
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
static const char *const TAG = "ble_text_sensor";
|
||||
|
||||
@@ -138,6 +137,5 @@ void BLETextSensor::update() {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
#endif
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
#ifdef USE_ESP32
|
||||
#include <esp_gattc_api.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
namespace esphome::ble_client {
|
||||
|
||||
namespace espbt = esphome::esp32_ble_tracker;
|
||||
|
||||
@@ -40,6 +39,5 @@ class BLETextSensor : public text_sensor::TextSensor, public PollingComponent, p
|
||||
espbt::ESPBTUUID descr_uuid_;
|
||||
};
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
} // namespace esphome::ble_client
|
||||
#endif
|
||||
|
||||
@@ -87,17 +87,21 @@ void BLENUS::setup() {
|
||||
global_ble_nus = this;
|
||||
#ifdef USE_LOGGER
|
||||
if (logger::global_logger != nullptr && this->expose_log_) {
|
||||
logger::global_logger->add_on_log_callback(
|
||||
[this](int level, const char *tag, const char *message, size_t message_len) {
|
||||
this->write_array(reinterpret_cast<const uint8_t *>(message), message_len);
|
||||
const char c = '\n';
|
||||
this->write_array(reinterpret_cast<const uint8_t *>(&c), 1);
|
||||
});
|
||||
logger::global_logger->add_log_listener(this);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_LOGGER
|
||||
void BLENUS::on_log(uint8_t level, const char *tag, const char *message, size_t message_len) {
|
||||
(void) level;
|
||||
(void) tag;
|
||||
this->write_array(reinterpret_cast<const uint8_t *>(message), message_len);
|
||||
const char c = '\n';
|
||||
this->write_array(reinterpret_cast<const uint8_t *>(&c), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void BLENUS::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "ble nus:");
|
||||
ESP_LOGCONFIG(TAG, " log: %s", YESNO(this->expose_log_));
|
||||
|
||||
@@ -2,12 +2,20 @@
|
||||
#ifdef USE_ZEPHYR
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/component.h"
|
||||
#ifdef USE_LOGGER
|
||||
#include "esphome/components/logger/logger.h"
|
||||
#endif
|
||||
#include <shell/shell_bt_nus.h>
|
||||
#include <atomic>
|
||||
|
||||
namespace esphome::ble_nus {
|
||||
|
||||
class BLENUS : public Component {
|
||||
class BLENUS : public Component
|
||||
#ifdef USE_LOGGER
|
||||
,
|
||||
public logger::LogListener
|
||||
#endif
|
||||
{
|
||||
enum TxStatus {
|
||||
TX_DISABLED,
|
||||
TX_ENABLED,
|
||||
@@ -20,6 +28,9 @@ class BLENUS : public Component {
|
||||
void loop() override;
|
||||
size_t write_array(const uint8_t *data, size_t len);
|
||||
void set_expose_log(bool expose_log) { this->expose_log_ = expose_log; }
|
||||
#ifdef USE_LOGGER
|
||||
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
static void send_enabled_callback(bt_nus_send_status status);
|
||||
|
||||
@@ -27,11 +27,13 @@ void BluetoothProxy::setup() {
|
||||
// Capture the configured scan mode from YAML before any API changes
|
||||
this->configured_scan_active_ = this->parent_->get_scan_active();
|
||||
|
||||
this->parent_->add_scanner_state_callback([this](esp32_ble_tracker::ScannerState state) {
|
||||
if (this->api_connection_ != nullptr) {
|
||||
this->send_bluetooth_scanner_state_(state);
|
||||
}
|
||||
});
|
||||
this->parent_->add_scanner_state_listener(this);
|
||||
}
|
||||
|
||||
void BluetoothProxy::on_scanner_state(esp32_ble_tracker::ScannerState state) {
|
||||
if (this->api_connection_ != nullptr) {
|
||||
this->send_bluetooth_scanner_state_(state);
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothProxy::send_bluetooth_scanner_state_(esp32_ble_tracker::ScannerState state) {
|
||||
|
||||
@@ -52,7 +52,9 @@ enum BluetoothProxySubscriptionFlag : uint32_t {
|
||||
SUBSCRIPTION_RAW_ADVERTISEMENTS = 1 << 0,
|
||||
};
|
||||
|
||||
class BluetoothProxy final : public esp32_ble_tracker::ESPBTDeviceListener, public Component {
|
||||
class BluetoothProxy final : public esp32_ble_tracker::ESPBTDeviceListener,
|
||||
public esp32_ble_tracker::BLEScannerStateListener,
|
||||
public Component {
|
||||
friend class BluetoothConnection; // Allow connection to update connections_free_response_
|
||||
public:
|
||||
BluetoothProxy();
|
||||
@@ -108,6 +110,9 @@ class BluetoothProxy final : public esp32_ble_tracker::ESPBTDeviceListener, publ
|
||||
void set_active(bool active) { this->active_ = active; }
|
||||
bool has_active() { return this->active_; }
|
||||
|
||||
/// BLEScannerStateListener interface
|
||||
void on_scanner_state(esp32_ble_tracker::ScannerState state) override;
|
||||
|
||||
uint32_t get_legacy_version() const {
|
||||
if (this->active_) {
|
||||
return LEGACY_ACTIVE_CONNECTIONS_VERSION;
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace button {
|
||||
namespace esphome::button {
|
||||
|
||||
template<typename... Ts> class PressAction : public Action<Ts...> {
|
||||
public:
|
||||
@@ -24,5 +23,4 @@ class ButtonPressTrigger : public Trigger<> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace button
|
||||
} // namespace esphome
|
||||
} // namespace esphome::button
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "button.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace button {
|
||||
namespace esphome::button {
|
||||
|
||||
static const char *const TAG = "button";
|
||||
|
||||
@@ -26,5 +25,4 @@ void Button::press() {
|
||||
}
|
||||
void Button::add_on_press_callback(std::function<void()> &&callback) { this->press_callback_.add(std::move(callback)); }
|
||||
|
||||
} // namespace button
|
||||
} // namespace esphome
|
||||
} // namespace esphome::button
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace button {
|
||||
namespace esphome::button {
|
||||
|
||||
class Button;
|
||||
void log_button(const char *tag, const char *prefix, const char *type, Button *obj);
|
||||
@@ -45,5 +44,4 @@ class Button : public EntityBase, public EntityBase_DeviceClass {
|
||||
CallbackManager<void()> press_callback_{};
|
||||
};
|
||||
|
||||
} // namespace button
|
||||
} // namespace esphome
|
||||
} // namespace esphome::button
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include "esphome/core/automation.h"
|
||||
#include "climate.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace climate {
|
||||
namespace esphome::climate {
|
||||
|
||||
template<typename... Ts> class ControlAction : public Action<Ts...> {
|
||||
public:
|
||||
@@ -58,5 +57,4 @@ class StateTrigger : public Trigger<Climate &> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace climate
|
||||
} // namespace esphome
|
||||
} // namespace esphome::climate
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include "esphome/core/controller_registry.h"
|
||||
#include "esphome/core/macros.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace climate {
|
||||
namespace esphome::climate {
|
||||
|
||||
static const char *const TAG = "climate";
|
||||
|
||||
@@ -762,5 +761,4 @@ void Climate::dump_traits_(const char *tag) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace climate
|
||||
} // namespace esphome
|
||||
} // namespace esphome::climate
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
#include "climate_mode.h"
|
||||
#include "climate_traits.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace climate {
|
||||
namespace esphome::climate {
|
||||
|
||||
#define LOG_CLIMATE(prefix, type, obj) \
|
||||
if ((obj) != nullptr) { \
|
||||
@@ -345,5 +344,4 @@ class Climate : public EntityBase {
|
||||
const char *custom_preset_{nullptr};
|
||||
};
|
||||
|
||||
} // namespace climate
|
||||
} // namespace esphome
|
||||
} // namespace esphome::climate
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "climate_mode.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace climate {
|
||||
namespace esphome::climate {
|
||||
|
||||
const LogString *climate_mode_to_string(ClimateMode mode) {
|
||||
switch (mode) {
|
||||
@@ -107,5 +106,4 @@ const LogString *climate_preset_to_string(ClimatePreset preset) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace climate
|
||||
} // namespace esphome
|
||||
} // namespace esphome::climate
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include <cstdint>
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace climate {
|
||||
namespace esphome::climate {
|
||||
|
||||
/// Enum for all modes a climate device can be in.
|
||||
/// NOTE: If adding values, update ClimateModeMask in climate_traits.h to use the new last value
|
||||
@@ -132,5 +131,4 @@ const LogString *climate_swing_mode_to_string(ClimateSwingMode mode);
|
||||
/// Convert the given PresetMode to a human-readable string.
|
||||
const LogString *climate_preset_to_string(ClimatePreset preset);
|
||||
|
||||
} // namespace climate
|
||||
} // namespace esphome
|
||||
} // namespace esphome::climate
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "climate_traits.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace climate {
|
||||
namespace esphome::climate {
|
||||
|
||||
int8_t ClimateTraits::get_target_temperature_accuracy_decimals() const {
|
||||
return step_to_accuracy_decimals(this->visual_target_temperature_step_);
|
||||
@@ -11,5 +10,4 @@ int8_t ClimateTraits::get_current_temperature_accuracy_decimals() const {
|
||||
return step_to_accuracy_decimals(this->visual_current_temperature_step_);
|
||||
}
|
||||
|
||||
} // namespace climate
|
||||
} // namespace esphome
|
||||
} // namespace esphome::climate
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
#include "esphome/core/finite_set_mask.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace climate {
|
||||
namespace esphome::climate {
|
||||
|
||||
// Type aliases for climate enum bitmasks
|
||||
// These replace std::set<EnumType> to eliminate red-black tree overhead
|
||||
@@ -292,5 +291,4 @@ class ClimateTraits {
|
||||
std::vector<const char *> supported_custom_presets_;
|
||||
};
|
||||
|
||||
} // namespace climate
|
||||
} // namespace esphome
|
||||
} // namespace esphome::climate
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace datetime {
|
||||
namespace esphome::datetime {
|
||||
|
||||
static const char *const TAG = "datetime.date_entity";
|
||||
|
||||
@@ -129,7 +128,6 @@ void DateEntityRestoreState::apply(DateEntity *date) {
|
||||
date->publish_state();
|
||||
}
|
||||
|
||||
} // namespace datetime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::datetime
|
||||
|
||||
#endif // USE_DATETIME_DATE
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
|
||||
#include "datetime_base.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace datetime {
|
||||
namespace esphome::datetime {
|
||||
|
||||
#define LOG_DATETIME_DATE(prefix, type, obj) \
|
||||
if ((obj) != nullptr) { \
|
||||
@@ -111,7 +110,6 @@ template<typename... Ts> class DateSetAction : public Action<Ts...>, public Pare
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace datetime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::datetime
|
||||
|
||||
#endif // USE_DATETIME_DATE
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
#include "esphome/components/time/real_time_clock.h"
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
namespace datetime {
|
||||
namespace esphome::datetime {
|
||||
|
||||
class DateTimeBase : public EntityBase {
|
||||
public:
|
||||
@@ -37,5 +36,4 @@ class DateTimeStateTrigger : public Trigger<ESPTime> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace datetime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::datetime
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace datetime {
|
||||
namespace esphome::datetime {
|
||||
|
||||
static const char *const TAG = "datetime.datetime_entity";
|
||||
|
||||
@@ -250,7 +249,6 @@ bool OnDateTimeTrigger::matches_(const ESPTime &time) const {
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace datetime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::datetime
|
||||
|
||||
#endif // USE_DATETIME_TIME
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
|
||||
#include "datetime_base.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace datetime {
|
||||
namespace esphome::datetime {
|
||||
|
||||
#define LOG_DATETIME_DATETIME(prefix, type, obj) \
|
||||
if ((obj) != nullptr) { \
|
||||
@@ -146,7 +145,6 @@ class OnDateTimeTrigger : public Trigger<>, public Component, public Parented<Da
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace datetime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::datetime
|
||||
|
||||
#endif // USE_DATETIME_DATETIME
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace datetime {
|
||||
namespace esphome::datetime {
|
||||
|
||||
static const char *const TAG = "datetime.time_entity";
|
||||
|
||||
@@ -152,7 +151,6 @@ bool OnTimeTrigger::matches_(const ESPTime &time) const {
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace datetime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::datetime
|
||||
|
||||
#endif // USE_DATETIME_TIME
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
|
||||
#include "datetime_base.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace datetime {
|
||||
namespace esphome::datetime {
|
||||
|
||||
#define LOG_DATETIME_TIME(prefix, type, obj) \
|
||||
if ((obj) != nullptr) { \
|
||||
@@ -125,7 +124,6 @@ class OnTimeTrigger : public Trigger<>, public Component, public Parented<TimeEn
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace datetime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::datetime
|
||||
|
||||
#endif // USE_DATETIME_TIME
|
||||
|
||||
@@ -33,7 +33,7 @@ class DemoAlarmControlPanel : public AlarmControlPanel, public Component {
|
||||
case ACP_STATE_ARMED_AWAY:
|
||||
if (this->get_requires_code_to_arm() && call.get_code().has_value()) {
|
||||
if (call.get_code().value() != "1234") {
|
||||
this->status_momentary_error("Invalid code", 5000);
|
||||
this->status_momentary_error("invalid_code", 5000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ class DemoAlarmControlPanel : public AlarmControlPanel, public Component {
|
||||
case ACP_STATE_DISARMED:
|
||||
if (this->get_requires_code() && call.get_code().has_value()) {
|
||||
if (call.get_code().value() != "1234") {
|
||||
this->status_momentary_error("Invalid code", 5000);
|
||||
this->status_momentary_error("invalid_code", 5000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ bool ES8388::set_dac_output(DacOutputLine line) {
|
||||
optional<DacOutputLine> ES8388::get_dac_power() {
|
||||
uint8_t dac_power;
|
||||
if (!this->read_byte(ES8388_DACPOWER, &dac_power)) {
|
||||
this->status_momentary_warning("Failed to read ES8388_DACPOWER");
|
||||
this->status_momentary_warning("dacpower_read");
|
||||
return {};
|
||||
}
|
||||
switch (dac_power) {
|
||||
@@ -268,7 +268,7 @@ bool ES8388::set_adc_input_mic(AdcInputMicLine line) {
|
||||
optional<AdcInputMicLine> ES8388::get_mic_input() {
|
||||
uint8_t mic_input;
|
||||
if (!this->read_byte(ES8388_ADCCONTROL2, &mic_input)) {
|
||||
this->status_momentary_warning("Failed to read ES8388_ADCCONTROL2");
|
||||
this->status_momentary_warning("adccontrol2_read");
|
||||
return {};
|
||||
}
|
||||
switch (mic_input) {
|
||||
|
||||
@@ -373,7 +373,9 @@ void ESP32BLETracker::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
|
||||
|
||||
void ESP32BLETracker::set_scanner_state_(ScannerState state) {
|
||||
this->scanner_state_ = state;
|
||||
this->scanner_state_callbacks_.call(state);
|
||||
for (auto *listener : this->scanner_state_listeners_) {
|
||||
listener->on_scanner_state(state);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_ESP32_BLE_DEVICE
|
||||
|
||||
@@ -180,6 +180,16 @@ enum class ScannerState {
|
||||
STOPPING,
|
||||
};
|
||||
|
||||
/** Listener interface for BLE scanner state changes.
|
||||
*
|
||||
* Components can implement this interface to receive scanner state updates
|
||||
* without the overhead of std::function callbacks.
|
||||
*/
|
||||
class BLEScannerStateListener {
|
||||
public:
|
||||
virtual void on_scanner_state(ScannerState state) = 0;
|
||||
};
|
||||
|
||||
// Helper function to convert ClientState to string
|
||||
const char *client_state_to_string(ClientState state);
|
||||
|
||||
@@ -264,8 +274,9 @@ class ESP32BLETracker : public Component,
|
||||
void gap_scan_event_handler(const BLEScanResult &scan_result) override;
|
||||
void ble_before_disabled_event_handler() override;
|
||||
|
||||
void add_scanner_state_callback(std::function<void(ScannerState)> &&callback) {
|
||||
this->scanner_state_callbacks_.add(std::move(callback));
|
||||
/// Add a listener for scanner state changes
|
||||
void add_scanner_state_listener(BLEScannerStateListener *listener) {
|
||||
this->scanner_state_listeners_.push_back(listener);
|
||||
}
|
||||
ScannerState get_scanner_state() const { return this->scanner_state_; }
|
||||
|
||||
@@ -322,14 +333,14 @@ class ESP32BLETracker : public Component,
|
||||
return counts;
|
||||
}
|
||||
|
||||
// Group 1: Large objects (12+ bytes) - vectors and callback manager
|
||||
// Group 1: Large objects (12+ bytes) - vectors
|
||||
#ifdef ESPHOME_ESP32_BLE_TRACKER_LISTENER_COUNT
|
||||
StaticVector<ESPBTDeviceListener *, ESPHOME_ESP32_BLE_TRACKER_LISTENER_COUNT> listeners_;
|
||||
#endif
|
||||
#ifdef ESPHOME_ESP32_BLE_TRACKER_CLIENT_COUNT
|
||||
StaticVector<ESPBTClient *, ESPHOME_ESP32_BLE_TRACKER_CLIENT_COUNT> clients_;
|
||||
#endif
|
||||
CallbackManager<void(ScannerState)> scanner_state_callbacks_;
|
||||
std::vector<BLEScannerStateListener *> scanner_state_listeners_;
|
||||
#ifdef USE_ESP32_BLE_DEVICE
|
||||
/// Vector of addresses that have already been printed in print_bt_device_info
|
||||
std::vector<uint64_t> already_discovered_;
|
||||
|
||||
@@ -10,6 +10,7 @@ from esphome.components.esp32.const import (
|
||||
VARIANT_ESP32C3,
|
||||
VARIANT_ESP32C6,
|
||||
VARIANT_ESP32H2,
|
||||
VARIANT_ESP32P4,
|
||||
VARIANT_ESP32S2,
|
||||
VARIANT_ESP32S3,
|
||||
)
|
||||
@@ -59,6 +60,7 @@ CAN_SPEEDS_ESP32_S3 = {**CAN_SPEEDS_ESP32_S2}
|
||||
CAN_SPEEDS_ESP32_C3 = {**CAN_SPEEDS_ESP32_S2}
|
||||
CAN_SPEEDS_ESP32_C6 = {**CAN_SPEEDS_ESP32_S2}
|
||||
CAN_SPEEDS_ESP32_H2 = {**CAN_SPEEDS_ESP32_S2}
|
||||
CAN_SPEEDS_ESP32_P4 = {**CAN_SPEEDS_ESP32_S2}
|
||||
|
||||
CAN_SPEEDS = {
|
||||
VARIANT_ESP32: CAN_SPEEDS_ESP32,
|
||||
@@ -67,6 +69,7 @@ CAN_SPEEDS = {
|
||||
VARIANT_ESP32C3: CAN_SPEEDS_ESP32_C3,
|
||||
VARIANT_ESP32C6: CAN_SPEEDS_ESP32_C6,
|
||||
VARIANT_ESP32H2: CAN_SPEEDS_ESP32_H2,
|
||||
VARIANT_ESP32P4: CAN_SPEEDS_ESP32_P4,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ static const char *const TAG = "esp32_can";
|
||||
static bool get_bitrate(canbus::CanSpeed bitrate, twai_timing_config_t *t_config) {
|
||||
switch (bitrate) {
|
||||
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C3) || \
|
||||
defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32H2)
|
||||
defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32H2) || defined(USE_ESP32_VARIANT_ESP32P4)
|
||||
case canbus::CAN_1KBPS:
|
||||
*t_config = (twai_timing_config_t) TWAI_TIMING_CONFIG_1KBITS();
|
||||
return true;
|
||||
|
||||
@@ -8,11 +8,13 @@ namespace esphome::esp8266 {
|
||||
static const char *const TAG = "esp8266";
|
||||
|
||||
static int flags_to_mode(gpio::Flags flags, uint8_t pin) {
|
||||
if (flags == gpio::FLAG_INPUT) { // NOLINT(bugprone-branch-clone)
|
||||
return INPUT;
|
||||
} else if (flags == gpio::FLAG_OUTPUT) {
|
||||
if (flags == gpio::FLAG_OUTPUT || flags == (gpio::FLAG_OUTPUT | gpio::FLAG_INPUT)) {
|
||||
return OUTPUT;
|
||||
} else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) {
|
||||
}
|
||||
if (flags == gpio::FLAG_INPUT) {
|
||||
return INPUT;
|
||||
}
|
||||
if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) {
|
||||
if (pin == 16) {
|
||||
// GPIO16 doesn't have a pullup, so pinMode would fail.
|
||||
// However, sometimes this method is called with pullup mode anyway
|
||||
@@ -21,13 +23,14 @@ static int flags_to_mode(gpio::Flags flags, uint8_t pin) {
|
||||
return INPUT;
|
||||
}
|
||||
return INPUT_PULLUP;
|
||||
} else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLDOWN)) {
|
||||
return INPUT_PULLDOWN_16;
|
||||
} else if (flags == (gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN)) {
|
||||
return OUTPUT_OPEN_DRAIN;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLDOWN)) {
|
||||
return INPUT_PULLDOWN_16;
|
||||
}
|
||||
if (flags == (gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN)) {
|
||||
return OUTPUT_OPEN_DRAIN;
|
||||
}
|
||||
return INPUT;
|
||||
}
|
||||
|
||||
struct ISRPinArg {
|
||||
|
||||
@@ -401,7 +401,7 @@ error:
|
||||
this->backend_->abort();
|
||||
}
|
||||
|
||||
this->status_momentary_error("onerror", 5000);
|
||||
this->status_momentary_error("err", 5000);
|
||||
#ifdef USE_OTA_STATE_CALLBACK
|
||||
this->state_callback_.call(ota::OTA_ERROR, 0.0f, static_cast<uint8_t>(error_code));
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <esp_event.h>
|
||||
#include <esp_mac.h>
|
||||
#include <esp_netif.h>
|
||||
#include <esp_now.h>
|
||||
#include <esp_random.h>
|
||||
#include <esp_wifi.h>
|
||||
@@ -157,6 +158,12 @@ bool ESPNowComponent::is_wifi_enabled() {
|
||||
}
|
||||
|
||||
void ESPNowComponent::setup() {
|
||||
#ifndef USE_WIFI
|
||||
// Initialize LwIP stack for wake_loop_threadsafe() socket support
|
||||
// When WiFi component is present, it handles esp_netif_init()
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
#endif
|
||||
|
||||
if (this->enable_on_boot_) {
|
||||
this->enable_();
|
||||
} else {
|
||||
|
||||
@@ -189,7 +189,7 @@ template<typename... Ts> class EnrollmentAction : public Action<Ts...>, public P
|
||||
TEMPLATABLE_VALUE(std::string, name)
|
||||
TEMPLATABLE_VALUE(uint8_t, direction)
|
||||
|
||||
void play(Ts... x) override {
|
||||
void play(const Ts &...x) override {
|
||||
auto name = this->name_.value(x...);
|
||||
auto direction = (HlkFm22xFaceDirection) this->direction_.value(x...);
|
||||
this->parent_->enroll_face(name, direction);
|
||||
@@ -200,7 +200,7 @@ template<typename... Ts> class DeleteAction : public Action<Ts...>, public Paren
|
||||
public:
|
||||
TEMPLATABLE_VALUE(int16_t, face_id)
|
||||
|
||||
void play(Ts... x) override {
|
||||
void play(const Ts &...x) override {
|
||||
auto face_id = this->face_id_.value(x...);
|
||||
this->parent_->delete_face(face_id);
|
||||
}
|
||||
@@ -208,17 +208,17 @@ template<typename... Ts> class DeleteAction : public Action<Ts...>, public Paren
|
||||
|
||||
template<typename... Ts> class DeleteAllAction : public Action<Ts...>, public Parented<HlkFm22xComponent> {
|
||||
public:
|
||||
void play(Ts... x) override { this->parent_->delete_all_faces(); }
|
||||
void play(const Ts &...x) override { this->parent_->delete_all_faces(); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class ScanAction : public Action<Ts...>, public Parented<HlkFm22xComponent> {
|
||||
public:
|
||||
void play(Ts... x) override { this->parent_->scan_face(); }
|
||||
void play(const Ts &...x) override { this->parent_->scan_face(); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class ResetAction : public Action<Ts...>, public Parented<HlkFm22xComponent> {
|
||||
public:
|
||||
void play(Ts... x) override { this->parent_->reset(); }
|
||||
void play(const Ts &...x) override { this->parent_->reset(); }
|
||||
};
|
||||
|
||||
} // namespace esphome::hlk_fm22x
|
||||
|
||||
@@ -74,11 +74,11 @@ static const LogString *color_mode_to_human(ColorMode color_mode) {
|
||||
|
||||
// Helper to log percentage values
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
|
||||
static void log_percent(const char *name, const char *param, float value) {
|
||||
ESP_LOGD(TAG, " %s: %.0f%%", param, value * 100.0f);
|
||||
static void log_percent(const LogString *param, float value) {
|
||||
ESP_LOGD(TAG, " %s: %.0f%%", LOG_STR_ARG(param), value * 100.0f);
|
||||
}
|
||||
#else
|
||||
#define log_percent(name, param, value)
|
||||
#define log_percent(param, value)
|
||||
#endif
|
||||
|
||||
void LightCall::perform() {
|
||||
@@ -104,11 +104,11 @@ void LightCall::perform() {
|
||||
}
|
||||
|
||||
if (this->has_brightness()) {
|
||||
log_percent(name, "Brightness", v.get_brightness());
|
||||
log_percent(LOG_STR("Brightness"), v.get_brightness());
|
||||
}
|
||||
|
||||
if (this->has_color_brightness()) {
|
||||
log_percent(name, "Color brightness", v.get_color_brightness());
|
||||
log_percent(LOG_STR("Color brightness"), v.get_color_brightness());
|
||||
}
|
||||
if (this->has_red() || this->has_green() || this->has_blue()) {
|
||||
ESP_LOGD(TAG, " Red: %.0f%%, Green: %.0f%%, Blue: %.0f%%", v.get_red() * 100.0f, v.get_green() * 100.0f,
|
||||
@@ -116,7 +116,7 @@ void LightCall::perform() {
|
||||
}
|
||||
|
||||
if (this->has_white()) {
|
||||
log_percent(name, "White", v.get_white());
|
||||
log_percent(LOG_STR("White"), v.get_white());
|
||||
}
|
||||
if (this->has_color_temperature()) {
|
||||
ESP_LOGD(TAG, " Color temperature: %.1f mireds", v.get_color_temperature());
|
||||
|
||||
@@ -7,30 +7,29 @@ namespace esphome::light {
|
||||
|
||||
// See https://www.home-assistant.io/integrations/light.mqtt/#json-schema for documentation on the schema
|
||||
|
||||
// Lookup table for color mode strings
|
||||
static constexpr const char *get_color_mode_json_str(ColorMode mode) {
|
||||
switch (mode) {
|
||||
case ColorMode::ON_OFF:
|
||||
return "onoff";
|
||||
case ColorMode::BRIGHTNESS:
|
||||
return "brightness";
|
||||
case ColorMode::WHITE:
|
||||
return "white"; // not supported by HA in MQTT
|
||||
case ColorMode::COLOR_TEMPERATURE:
|
||||
return "color_temp";
|
||||
case ColorMode::COLD_WARM_WHITE:
|
||||
return "cwww"; // not supported by HA
|
||||
case ColorMode::RGB:
|
||||
return "rgb";
|
||||
case ColorMode::RGB_WHITE:
|
||||
return "rgbw";
|
||||
case ColorMode::RGB_COLOR_TEMPERATURE:
|
||||
return "rgbct"; // not supported by HA
|
||||
case ColorMode::RGB_COLD_WARM_WHITE:
|
||||
return "rgbww";
|
||||
default:
|
||||
return nullptr;
|
||||
// Get JSON string for color mode using linear search (avoids large switch jump table)
|
||||
static const char *get_color_mode_json_str(ColorMode mode) {
|
||||
// Parallel arrays: mode values and their corresponding strings
|
||||
// Uses less RAM than a switch jump table on sparse enum values
|
||||
static constexpr ColorMode MODES[] = {
|
||||
ColorMode::ON_OFF,
|
||||
ColorMode::BRIGHTNESS,
|
||||
ColorMode::WHITE,
|
||||
ColorMode::COLOR_TEMPERATURE,
|
||||
ColorMode::COLD_WARM_WHITE,
|
||||
ColorMode::RGB,
|
||||
ColorMode::RGB_WHITE,
|
||||
ColorMode::RGB_COLOR_TEMPERATURE,
|
||||
ColorMode::RGB_COLD_WARM_WHITE,
|
||||
};
|
||||
static constexpr const char *STRINGS[] = {
|
||||
"onoff", "brightness", "white", "color_temp", "cwww", "rgb", "rgbw", "rgbct", "rgbww",
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(MODES) / sizeof(MODES[0]); i++) {
|
||||
if (MODES[i] == mode)
|
||||
return STRINGS[i];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void LightJSONSchema::dump_json(LightState &state, JsonObject root) {
|
||||
|
||||
@@ -49,26 +49,18 @@ template<typename... Ts> class LockCondition : public Condition<Ts...> {
|
||||
bool state_;
|
||||
};
|
||||
|
||||
class LockLockTrigger : public Trigger<> {
|
||||
template<LockState State> class LockStateTrigger : public Trigger<> {
|
||||
public:
|
||||
LockLockTrigger(Lock *a_lock) {
|
||||
explicit LockStateTrigger(Lock *a_lock) {
|
||||
a_lock->add_on_state_callback([this, a_lock]() {
|
||||
if (a_lock->state == LockState::LOCK_STATE_LOCKED) {
|
||||
if (a_lock->state == State) {
|
||||
this->trigger();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
class LockUnlockTrigger : public Trigger<> {
|
||||
public:
|
||||
LockUnlockTrigger(Lock *a_lock) {
|
||||
a_lock->add_on_state_callback([this, a_lock]() {
|
||||
if (a_lock->state == LockState::LOCK_STATE_UNLOCKED) {
|
||||
this->trigger();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
using LockLockTrigger = LockStateTrigger<LockState::LOCK_STATE_LOCKED>;
|
||||
using LockUnlockTrigger = LockStateTrigger<LockState::LOCK_STATE_UNLOCKED>;
|
||||
|
||||
} // namespace esphome::lock
|
||||
|
||||
@@ -406,6 +406,8 @@ async def to_code(config):
|
||||
conf,
|
||||
)
|
||||
|
||||
CORE.add_job(final_step)
|
||||
|
||||
|
||||
def validate_printf(value):
|
||||
# https://stackoverflow.com/questions/30011379/how-can-i-parse-a-c-format-string-in-python
|
||||
@@ -506,3 +508,24 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform(
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
# Keys for CORE.data storage
|
||||
DOMAIN = "logger"
|
||||
KEY_LEVEL_LISTENERS = "level_listeners"
|
||||
|
||||
|
||||
def request_logger_level_listeners() -> None:
|
||||
"""Request that logger level listeners be compiled in.
|
||||
|
||||
Components that need to be notified about log level changes should call this
|
||||
function during their code generation. This enables the add_level_listener()
|
||||
method and compiles in the listener vector.
|
||||
"""
|
||||
CORE.data.setdefault(DOMAIN, {})[KEY_LEVEL_LISTENERS] = True
|
||||
|
||||
|
||||
@coroutine_with_priority(CoroPriority.FINAL)
|
||||
async def final_step():
|
||||
"""Final code generation step to configure optional logger features."""
|
||||
if CORE.data.get(DOMAIN, {}).get(KEY_LEVEL_LISTENERS, False):
|
||||
cg.add_define("USE_LOGGER_LEVEL_LISTENERS")
|
||||
|
||||
@@ -140,8 +140,9 @@ void Logger::log_vprintf_(uint8_t level, const char *tag, int line, const __Flas
|
||||
uint16_t msg_length =
|
||||
this->tx_buffer_at_ - msg_start; // Don't subtract 1 - tx_buffer_at_ is already at the null terminator position
|
||||
|
||||
// Callbacks get message first (before console write)
|
||||
this->log_callback_.call(level, tag, this->tx_buffer_ + msg_start, msg_length);
|
||||
// Listeners get message first (before console write)
|
||||
for (auto *listener : this->log_listeners_)
|
||||
listener->on_log(level, tag, this->tx_buffer_ + msg_start, msg_length);
|
||||
|
||||
// Write to console starting at the msg_start
|
||||
this->write_tx_buffer_to_console_(msg_start, &msg_length);
|
||||
@@ -203,7 +204,8 @@ void Logger::process_messages_() {
|
||||
this->write_footer_to_buffer_(this->tx_buffer_, &this->tx_buffer_at_, this->tx_buffer_size_);
|
||||
this->tx_buffer_[this->tx_buffer_at_] = '\0';
|
||||
size_t msg_len = this->tx_buffer_at_; // We already know the length from tx_buffer_at_
|
||||
this->log_callback_.call(message->level, message->tag, this->tx_buffer_, msg_len);
|
||||
for (auto *listener : this->log_listeners_)
|
||||
listener->on_log(message->level, message->tag, this->tx_buffer_, msg_len);
|
||||
// At this point all the data we need from message has been transferred to the tx_buffer
|
||||
// so we can release the message to allow other tasks to use it as soon as possible.
|
||||
this->log_buffer_->release_message_main_loop(received_token);
|
||||
@@ -231,9 +233,6 @@ void Logger::set_log_level(const char *tag, uint8_t log_level) { this->log_level
|
||||
UARTSelection Logger::get_uart() const { return this->uart_; }
|
||||
#endif
|
||||
|
||||
void Logger::add_on_log_callback(std::function<void(uint8_t, const char *, const char *, size_t)> &&callback) {
|
||||
this->log_callback_.add(std::move(callback));
|
||||
}
|
||||
float Logger::get_setup_priority() const { return setup_priority::BUS + 500.0f; }
|
||||
|
||||
#ifdef USE_STORE_LOG_STR_IN_FLASH
|
||||
@@ -289,7 +288,10 @@ void Logger::set_log_level(uint8_t level) {
|
||||
ESP_LOGW(TAG, "Cannot set log level higher than pre-compiled %s", LOG_STR_ARG(LOG_LEVELS[ESPHOME_LOG_LEVEL]));
|
||||
}
|
||||
this->current_level_ = level;
|
||||
this->level_callback_.call(level);
|
||||
#ifdef USE_LOGGER_LEVEL_LISTENERS
|
||||
for (auto *listener : this->level_listeners_)
|
||||
listener->on_log_level_change(level);
|
||||
#endif
|
||||
}
|
||||
|
||||
Logger *global_logger = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
@@ -36,6 +36,52 @@ struct device;
|
||||
|
||||
namespace esphome::logger {
|
||||
|
||||
/** Interface for receiving log messages without std::function overhead.
|
||||
*
|
||||
* Components can implement this interface instead of using lambdas with std::function
|
||||
* to reduce flash usage from std::function type erasure machinery.
|
||||
*
|
||||
* Usage:
|
||||
* class MyComponent : public Component, public LogListener {
|
||||
* public:
|
||||
* void setup() override {
|
||||
* if (logger::global_logger != nullptr)
|
||||
* logger::global_logger->add_log_listener(this);
|
||||
* }
|
||||
* void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override {
|
||||
* // Handle log message
|
||||
* }
|
||||
* };
|
||||
*/
|
||||
class LogListener {
|
||||
public:
|
||||
virtual void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) = 0;
|
||||
};
|
||||
|
||||
#ifdef USE_LOGGER_LEVEL_LISTENERS
|
||||
/** Interface for receiving log level changes without std::function overhead.
|
||||
*
|
||||
* Components can implement this interface instead of using lambdas with std::function
|
||||
* to reduce flash usage from std::function type erasure machinery.
|
||||
*
|
||||
* Usage:
|
||||
* class MyComponent : public Component, public LoggerLevelListener {
|
||||
* public:
|
||||
* void setup() override {
|
||||
* if (logger::global_logger != nullptr)
|
||||
* logger::global_logger->add_logger_level_listener(this);
|
||||
* }
|
||||
* void on_log_level_change(uint8_t level) override {
|
||||
* // Handle log level change
|
||||
* }
|
||||
* };
|
||||
*/
|
||||
class LoggerLevelListener {
|
||||
public:
|
||||
virtual void on_log_level_change(uint8_t level) = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS
|
||||
// Comparison function for const char* keys in log_levels_ map
|
||||
struct CStrCompare {
|
||||
@@ -168,11 +214,13 @@ class Logger : public Component {
|
||||
|
||||
inline uint8_t level_for(const char *tag);
|
||||
|
||||
/// Register a callback that will be called for every log message sent
|
||||
void add_on_log_callback(std::function<void(uint8_t, const char *, const char *, size_t)> &&callback);
|
||||
/// Register a log listener to receive log messages
|
||||
void add_log_listener(LogListener *listener) { this->log_listeners_.push_back(listener); }
|
||||
|
||||
// add a listener for log level changes
|
||||
void add_listener(std::function<void(uint8_t)> &&callback) { this->level_callback_.add(std::move(callback)); }
|
||||
#ifdef USE_LOGGER_LEVEL_LISTENERS
|
||||
/// Register a listener for log level changes
|
||||
void add_level_listener(LoggerLevelListener *listener) { this->level_listeners_.push_back(listener); }
|
||||
#endif
|
||||
|
||||
float get_setup_priority() const override;
|
||||
|
||||
@@ -240,7 +288,7 @@ class Logger : public Component {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to format and send a log message to both console and callbacks
|
||||
// Helper to format and send a log message to both console and listeners
|
||||
inline void HOT log_message_to_buffer_and_send_(uint8_t level, const char *tag, int line, const char *format,
|
||||
va_list args) {
|
||||
// Format to tx_buffer and prepare for output
|
||||
@@ -248,8 +296,9 @@ class Logger : public Component {
|
||||
this->format_log_to_buffer_with_terminator_(level, tag, line, format, args, this->tx_buffer_, &this->tx_buffer_at_,
|
||||
this->tx_buffer_size_);
|
||||
|
||||
// Callbacks get message WITHOUT newline (for API/MQTT/syslog)
|
||||
this->log_callback_.call(level, tag, this->tx_buffer_, this->tx_buffer_at_);
|
||||
// Listeners get message WITHOUT newline (for API/MQTT/syslog)
|
||||
for (auto *listener : this->log_listeners_)
|
||||
listener->on_log(level, tag, this->tx_buffer_, this->tx_buffer_at_);
|
||||
|
||||
// Console gets message WITH newline (if platform needs it)
|
||||
this->write_tx_buffer_to_console_();
|
||||
@@ -301,8 +350,10 @@ class Logger : public Component {
|
||||
#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS
|
||||
std::map<const char *, uint8_t, CStrCompare> log_levels_{};
|
||||
#endif
|
||||
CallbackManager<void(uint8_t, const char *, const char *, size_t)> log_callback_{};
|
||||
CallbackManager<void(uint8_t)> level_callback_{};
|
||||
std::vector<LogListener *> log_listeners_; // Log message listeners (API, MQTT, syslog, etc.)
|
||||
#ifdef USE_LOGGER_LEVEL_LISTENERS
|
||||
std::vector<LoggerLevelListener *> level_listeners_; // Log level change listeners
|
||||
#endif
|
||||
#ifdef USE_ESPHOME_TASK_LOG_BUFFER
|
||||
std::unique_ptr<logger::TaskLogBuffer> log_buffer_; // Will be initialized with init_log_buffer
|
||||
#endif
|
||||
@@ -496,15 +547,15 @@ class Logger : public Component {
|
||||
};
|
||||
extern Logger *global_logger; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
class LoggerMessageTrigger : public Trigger<uint8_t, const char *, const char *> {
|
||||
class LoggerMessageTrigger : public Trigger<uint8_t, const char *, const char *>, public LogListener {
|
||||
public:
|
||||
explicit LoggerMessageTrigger(Logger *parent, uint8_t level) {
|
||||
this->level_ = level;
|
||||
parent->add_on_log_callback([this](uint8_t level, const char *tag, const char *message, size_t message_len) {
|
||||
if (level <= this->level_) {
|
||||
this->trigger(level, tag, message);
|
||||
}
|
||||
});
|
||||
explicit LoggerMessageTrigger(Logger *parent, uint8_t level) : level_(level) { parent->add_log_listener(this); }
|
||||
|
||||
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override {
|
||||
(void) message_len;
|
||||
if (level <= this->level_) {
|
||||
this->trigger(level, tag, message);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -5,7 +5,13 @@ from esphome.const import CONF_LEVEL, CONF_LOGGER, ENTITY_CATEGORY_CONFIG, ICON_
|
||||
from esphome.core import CORE
|
||||
from esphome.cpp_helpers import register_component, register_parented
|
||||
|
||||
from .. import CONF_LOGGER_ID, LOG_LEVELS, Logger, logger_ns
|
||||
from .. import (
|
||||
CONF_LOGGER_ID,
|
||||
LOG_LEVELS,
|
||||
Logger,
|
||||
logger_ns,
|
||||
request_logger_level_listeners,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@clydebarrow"]
|
||||
|
||||
@@ -21,6 +27,7 @@ CONFIG_SCHEMA = select.select_schema(
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
request_logger_level_listeners()
|
||||
parent = await cg.get_variable(config[CONF_LOGGER_ID])
|
||||
levels = list(LOG_LEVELS)
|
||||
index = levels.index(CORE.data[CONF_LOGGER][CONF_LEVEL])
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace esphome::logger {
|
||||
|
||||
void LoggerLevelSelect::publish_state(int level) {
|
||||
void LoggerLevelSelect::on_log_level_change(uint8_t level) {
|
||||
auto index = level_to_index(level);
|
||||
if (!this->has_index(index))
|
||||
return;
|
||||
@@ -10,8 +10,8 @@ void LoggerLevelSelect::publish_state(int level) {
|
||||
}
|
||||
|
||||
void LoggerLevelSelect::setup() {
|
||||
this->parent_->add_listener([this](int level) { this->publish_state(level); });
|
||||
this->publish_state(this->parent_->get_log_level());
|
||||
this->parent_->add_level_listener(this);
|
||||
this->on_log_level_change(this->parent_->get_log_level());
|
||||
}
|
||||
|
||||
void LoggerLevelSelect::control(size_t index) { this->parent_->set_log_level(index_to_level(index)); }
|
||||
|
||||
@@ -5,12 +5,17 @@
|
||||
#include "esphome/components/logger/logger.h"
|
||||
|
||||
namespace esphome::logger {
|
||||
class LoggerLevelSelect : public Component, public select::Select, public Parented<Logger> {
|
||||
class LoggerLevelSelect final : public Component,
|
||||
public select::Select,
|
||||
public Parented<Logger>,
|
||||
public LoggerLevelListener {
|
||||
public:
|
||||
void publish_state(int level);
|
||||
void setup() override;
|
||||
void control(size_t index) override;
|
||||
|
||||
// LoggerLevelListener interface
|
||||
void on_log_level_change(uint8_t level) 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; }
|
||||
|
||||
@@ -165,7 +165,7 @@ async def to_code(config):
|
||||
cg.add_library("LEAmDNS", None)
|
||||
|
||||
if CORE.using_esp_idf:
|
||||
add_idf_component(name="espressif/mdns", ref="1.8.2")
|
||||
add_idf_component(name="espressif/mdns", ref="1.9.1")
|
||||
|
||||
cg.add_define("USE_MDNS")
|
||||
|
||||
|
||||
@@ -298,8 +298,7 @@ void MicroWakeWord::loop() {
|
||||
// uses floating point operations.
|
||||
if (!FrontendPopulateState(&this->frontend_config_, &this->frontend_state_,
|
||||
this->microphone_source_->get_audio_stream_info().get_sample_rate())) {
|
||||
this->status_momentary_error(
|
||||
"Failed to allocate buffers for spectrogram feature processor, attempting again in 1 second", 1000);
|
||||
this->status_momentary_error("frontend_alloc", 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -308,7 +307,7 @@ void MicroWakeWord::loop() {
|
||||
|
||||
if (this->inference_task_handle_ == nullptr) {
|
||||
FrontendFreeStateContents(&this->frontend_state_); // Deallocate frontend state
|
||||
this->status_momentary_error("Task failed to start, attempting again in 1 second", 1000);
|
||||
this->status_momentary_error("task_start", 1000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "micronova_button.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
void MicroNovaButton::press_action() {
|
||||
switch (this->get_function()) {
|
||||
@@ -14,5 +13,4 @@ void MicroNovaButton::press_action() {
|
||||
this->micronova_->update();
|
||||
}
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/button/button.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
class MicroNovaButton : public Component, public button::Button, public MicroNovaButtonListener {
|
||||
public:
|
||||
@@ -19,5 +18,4 @@ class MicroNovaButton : public Component, public button::Button, public MicroNov
|
||||
void press_action() override;
|
||||
};
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "micronova.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
void MicroNova::setup() {
|
||||
if (this->enable_rx_pin_ != nullptr) {
|
||||
@@ -144,5 +143,4 @@ void MicroNova::write_address(uint8_t location, uint8_t address, uint8_t data) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
static const char *const TAG = "micronova";
|
||||
static const int STOVE_REPLY_DELAY = 60;
|
||||
@@ -160,5 +159,4 @@ class MicroNova : public PollingComponent, public uart::UARTDevice {
|
||||
MicroNovaSwitchListener *stove_switch_{nullptr};
|
||||
};
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "micronova_number.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
void MicroNovaNumber::process_value_from_stove(int value_from_stove) {
|
||||
float new_sensor_value = 0;
|
||||
@@ -41,5 +40,4 @@ void MicroNovaNumber::control(float value) {
|
||||
this->micronova_->update();
|
||||
}
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include "esphome/components/micronova/micronova.h"
|
||||
#include "esphome/components/number/number.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
class MicroNovaNumber : public number::Number, public MicroNovaSensorListener {
|
||||
public:
|
||||
@@ -24,5 +23,4 @@ class MicroNovaNumber : public number::Number, public MicroNovaSensorListener {
|
||||
uint8_t memory_write_location_ = 0;
|
||||
};
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "micronova_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
void MicroNovaSensor::process_value_from_stove(int value_from_stove) {
|
||||
if (value_from_stove == -1) {
|
||||
@@ -31,5 +30,4 @@ void MicroNovaSensor::process_value_from_stove(int value_from_stove) {
|
||||
this->publish_state(new_sensor_value);
|
||||
}
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include "esphome/components/micronova/micronova.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
class MicroNovaSensor : public sensor::Sensor, public MicroNovaSensorListener {
|
||||
public:
|
||||
@@ -23,5 +22,4 @@ class MicroNovaSensor : public sensor::Sensor, public MicroNovaSensorListener {
|
||||
int fan_speed_offset_ = 0;
|
||||
};
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "micronova_switch.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
void MicroNovaSwitch::write_state(bool state) {
|
||||
switch (this->get_function()) {
|
||||
@@ -31,5 +30,4 @@ void MicroNovaSwitch::write_state(bool state) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/switch/switch.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
class MicroNovaSwitch : public Component, public switch_::Switch, public MicroNovaSwitchListener {
|
||||
public:
|
||||
@@ -25,5 +24,4 @@ class MicroNovaSwitch : public Component, public switch_::Switch, public MicroNo
|
||||
void write_state(bool state) override;
|
||||
};
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "micronova_text_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
void MicroNovaTextSensor::process_value_from_stove(int value_from_stove) {
|
||||
if (value_from_stove == -1) {
|
||||
@@ -27,5 +26,4 @@ void MicroNovaTextSensor::process_value_from_stove(int value_from_stove) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include "esphome/components/micronova/micronova.h"
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace micronova {
|
||||
namespace esphome::micronova {
|
||||
|
||||
class MicroNovaTextSensor : public text_sensor::TextSensor, public MicroNovaSensorListener {
|
||||
public:
|
||||
@@ -16,5 +15,4 @@ class MicroNovaTextSensor : public text_sensor::TextSensor, public MicroNovaSens
|
||||
void process_value_from_stove(int value_from_stove) override;
|
||||
};
|
||||
|
||||
} // namespace micronova
|
||||
} // namespace esphome
|
||||
} // namespace esphome::micronova
|
||||
|
||||
@@ -484,4 +484,109 @@ DriverChip(
|
||||
),
|
||||
)
|
||||
|
||||
DriverChip(
|
||||
"JC4827W543",
|
||||
height=272,
|
||||
width=480,
|
||||
offset_height=0,
|
||||
offset_width=0,
|
||||
cs_pin={CONF_NUMBER: 45, CONF_IGNORE_STRAPPING_WARNING: True},
|
||||
invert_colors=True,
|
||||
color_order=MODE_RGB,
|
||||
bus_mode=TYPE_QUAD,
|
||||
data_rate="20MHz",
|
||||
initsequence=(
|
||||
(0xFF, 0xA5),
|
||||
(0x41, 0x03),
|
||||
(0x44, 0x15),
|
||||
(0x45, 0x15),
|
||||
(0x7D, 0x03),
|
||||
(0xC1, 0xBB),
|
||||
(0xC2, 0x05),
|
||||
(0xC3, 0x10),
|
||||
(0xC6, 0x3E),
|
||||
(0xC7, 0x25),
|
||||
(0xC8, 0x11),
|
||||
(0x7A, 0x5F),
|
||||
(0x6F, 0x44),
|
||||
(0x78, 0x70),
|
||||
(0xC9, 0x00),
|
||||
(0x67, 0x21),
|
||||
(0x51, 0x0A),
|
||||
(0x52, 0x76),
|
||||
(0x53, 0x0A),
|
||||
(0x54, 0x76),
|
||||
(0x46, 0x0A),
|
||||
(0x47, 0x2A),
|
||||
(0x48, 0x0A),
|
||||
(0x49, 0x1A),
|
||||
(0x56, 0x43),
|
||||
(0x57, 0x42),
|
||||
(0x58, 0x3C),
|
||||
(0x59, 0x64),
|
||||
(0x5A, 0x41),
|
||||
(0x5B, 0x3C),
|
||||
(0x5C, 0x02),
|
||||
(0x5D, 0x3C),
|
||||
(0x5E, 0x1F),
|
||||
(0x60, 0x80),
|
||||
(0x61, 0x3F),
|
||||
(0x62, 0x21),
|
||||
(0x63, 0x07),
|
||||
(0x64, 0xE0),
|
||||
(0x65, 0x02),
|
||||
(0xCA, 0x20),
|
||||
(0xCB, 0x52),
|
||||
(0xCC, 0x10),
|
||||
(0xCD, 0x42),
|
||||
(0xD0, 0x20),
|
||||
(0xD1, 0x52),
|
||||
(0xD2, 0x10),
|
||||
(0xD3, 0x42),
|
||||
(0xD4, 0x0A),
|
||||
(0xD5, 0x32),
|
||||
(0x80, 0x00),
|
||||
(0xA0, 0x00),
|
||||
(0x81, 0x07),
|
||||
(0xA1, 0x06),
|
||||
(0x82, 0x02),
|
||||
(0xA2, 0x01),
|
||||
(0x86, 0x11),
|
||||
(0xA6, 0x10),
|
||||
(0x87, 0x27),
|
||||
(0xA7, 0x27),
|
||||
(0x83, 0x37),
|
||||
(0xA3, 0x37),
|
||||
(0x84, 0x35),
|
||||
(0xA4, 0x35),
|
||||
(0x85, 0x3F),
|
||||
(0xA5, 0x3F),
|
||||
(0x88, 0x0B),
|
||||
(0xA8, 0x0B),
|
||||
(0x89, 0x14),
|
||||
(0xA9, 0x14),
|
||||
(0x8A, 0x1A),
|
||||
(0xAA, 0x1A),
|
||||
(0x8B, 0x0A),
|
||||
(0xAB, 0x0A),
|
||||
(0x8C, 0x14),
|
||||
(0xAC, 0x08),
|
||||
(0x8D, 0x17),
|
||||
(0xAD, 0x07),
|
||||
(0x8E, 0x16),
|
||||
(0xAE, 0x06),
|
||||
(0x8F, 0x1B),
|
||||
(0xAF, 0x07),
|
||||
(0x90, 0x04),
|
||||
(0xB0, 0x04),
|
||||
(0x91, 0x0A),
|
||||
(0xB1, 0x0A),
|
||||
(0x92, 0x16),
|
||||
(0xB2, 0x15),
|
||||
(0xFF, 0x00),
|
||||
(0x11, 0x00),
|
||||
(0x29, 0x00),
|
||||
),
|
||||
)
|
||||
|
||||
models = {}
|
||||
|
||||
@@ -116,7 +116,7 @@ bool MopekaProCheck::parse_device(const esp32_ble_tracker::ESPBTDevice &device)
|
||||
|
||||
// Get temperature of sensor
|
||||
if (this->temperature_ != nullptr) {
|
||||
uint8_t temp_in_c = this->parse_temperature_(manu_data.data);
|
||||
int8_t temp_in_c = this->parse_temperature_(manu_data.data);
|
||||
this->temperature_->publish_state(temp_in_c);
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ uint32_t MopekaProCheck::parse_distance_(const std::vector<uint8_t> &message) {
|
||||
(MOPEKA_LPG_COEF[0] + MOPEKA_LPG_COEF[1] * raw_t + MOPEKA_LPG_COEF[2] * raw_t * raw_t));
|
||||
}
|
||||
|
||||
uint8_t MopekaProCheck::parse_temperature_(const std::vector<uint8_t> &message) { return (message[2] & 0x7F) - 40; }
|
||||
int8_t MopekaProCheck::parse_temperature_(const std::vector<uint8_t> &message) { return (message[2] & 0x7F) - 40; }
|
||||
|
||||
SensorReadQuality MopekaProCheck::parse_read_quality_(const std::vector<uint8_t> &message) {
|
||||
// Since a 8 bit value is being shifted and truncated to 2 bits all possible values are defined as enumeration
|
||||
|
||||
@@ -61,7 +61,7 @@ class MopekaProCheck : public Component, public esp32_ble_tracker::ESPBTDeviceLi
|
||||
|
||||
uint8_t parse_battery_level_(const std::vector<uint8_t> &message);
|
||||
uint32_t parse_distance_(const std::vector<uint8_t> &message);
|
||||
uint8_t parse_temperature_(const std::vector<uint8_t> &message);
|
||||
int8_t parse_temperature_(const std::vector<uint8_t> &message);
|
||||
SensorReadQuality parse_read_quality_(const std::vector<uint8_t> &message);
|
||||
};
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ from esphome.const import (
|
||||
PLATFORM_BK72XX,
|
||||
PLATFORM_ESP32,
|
||||
PLATFORM_ESP8266,
|
||||
PLATFORM_RTL87XX,
|
||||
PlatformFramework,
|
||||
)
|
||||
from esphome.core import CORE, CoroPriority, coroutine_with_priority
|
||||
@@ -316,7 +317,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
}
|
||||
),
|
||||
validate_config,
|
||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_BK72XX]),
|
||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_BK72XX, PLATFORM_RTL87XX]),
|
||||
_consume_mqtt_sockets,
|
||||
)
|
||||
|
||||
|
||||
@@ -57,15 +57,7 @@ void MQTTClientComponent::setup() {
|
||||
});
|
||||
#ifdef USE_LOGGER
|
||||
if (this->is_log_message_enabled() && logger::global_logger != nullptr) {
|
||||
logger::global_logger->add_on_log_callback(
|
||||
[this](int level, const char *tag, const char *message, size_t message_len) {
|
||||
if (level <= this->log_level_ && this->is_connected()) {
|
||||
this->publish({.topic = this->log_message_.topic,
|
||||
.payload = std::string(message, message_len),
|
||||
.qos = this->log_message_.qos,
|
||||
.retain = this->log_message_.retain});
|
||||
}
|
||||
});
|
||||
logger::global_logger->add_log_listener(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -148,6 +140,18 @@ void MQTTClientComponent::send_device_info_() {
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
#ifdef USE_LOGGER
|
||||
void MQTTClientComponent::on_log(uint8_t level, const char *tag, const char *message, size_t message_len) {
|
||||
(void) tag;
|
||||
if (level <= this->log_level_ && this->is_connected()) {
|
||||
this->publish({.topic = this->log_message_.topic,
|
||||
.payload = std::string(message, message_len),
|
||||
.qos = this->log_message_.qos,
|
||||
.retain = this->log_message_.retain});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void MQTTClientComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"MQTT:\n"
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#ifdef USE_LOGGER
|
||||
#include "esphome/components/logger/logger.h"
|
||||
#endif
|
||||
#if defined(USE_ESP32)
|
||||
#include "mqtt_backend_esp32.h"
|
||||
#elif defined(USE_ESP8266)
|
||||
@@ -97,7 +100,12 @@ enum MQTTClientState {
|
||||
|
||||
class MQTTComponent;
|
||||
|
||||
class MQTTClientComponent : public Component {
|
||||
class MQTTClientComponent : public Component
|
||||
#ifdef USE_LOGGER
|
||||
,
|
||||
public logger::LogListener
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
MQTTClientComponent();
|
||||
|
||||
@@ -238,6 +246,10 @@ class MQTTClientComponent : public Component {
|
||||
/// MQTT client setup priority
|
||||
float get_setup_priority() const override;
|
||||
|
||||
#ifdef USE_LOGGER
|
||||
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override;
|
||||
#endif
|
||||
|
||||
void on_message(const std::string &topic, const std::string &payload);
|
||||
|
||||
bool can_proceed() override;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace esphome::number {
|
||||
|
||||
class Number;
|
||||
|
||||
enum NumberOperation {
|
||||
enum NumberOperation : uint8_t {
|
||||
NUMBER_OP_NONE,
|
||||
NUMBER_OP_SET,
|
||||
NUMBER_OP_INCREMENT,
|
||||
@@ -38,9 +38,9 @@ class NumberCall {
|
||||
float limit);
|
||||
|
||||
Number *const parent_;
|
||||
NumberOperation operation_{NUMBER_OP_NONE};
|
||||
optional<float> value_;
|
||||
bool cycle_;
|
||||
NumberOperation operation_{NUMBER_OP_NONE};
|
||||
bool cycle_{false};
|
||||
};
|
||||
|
||||
} // namespace esphome::number
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.esp32 import (
|
||||
VARIANT_ESP32C5,
|
||||
VARIANT_ESP32C6,
|
||||
VARIANT_ESP32H2,
|
||||
add_idf_sdkconfig_option,
|
||||
@@ -152,7 +153,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
).extend(_CONNECTION_SCHEMA),
|
||||
cv.has_exactly_one_key(CONF_NETWORK_KEY, CONF_TLV),
|
||||
cv.only_with_esp_idf,
|
||||
only_on_variant(supported=[VARIANT_ESP32C6, VARIANT_ESP32H2]),
|
||||
only_on_variant(supported=[VARIANT_ESP32C5, VARIANT_ESP32C6, VARIANT_ESP32H2]),
|
||||
_validate,
|
||||
_require_vfs_select,
|
||||
)
|
||||
|
||||
@@ -2,7 +2,8 @@ import logging
|
||||
from pathlib import Path
|
||||
|
||||
from esphome import git, yaml_util
|
||||
from esphome.config_helpers import merge_config
|
||||
from esphome.components.substitutions.jinja import has_jinja
|
||||
from esphome.config_helpers import Remove, merge_config
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ESPHOME,
|
||||
@@ -39,10 +40,15 @@ def valid_package_contents(package_config: dict):
|
||||
for k, v in package_config.items():
|
||||
if not isinstance(k, str):
|
||||
raise cv.Invalid("Package content keys must be strings")
|
||||
if isinstance(v, (dict, list)):
|
||||
continue # e.g. script: [] or logger: {level: debug}
|
||||
if isinstance(v, (dict, list, Remove)):
|
||||
continue # e.g. script: [], psram: !remove, logger: {level: debug}
|
||||
if v is None:
|
||||
continue # e.g. web_server:
|
||||
if isinstance(v, str) and has_jinja(v):
|
||||
# e.g: remote package shorthand:
|
||||
# package_name: github://esphome/repo/file.yaml@${ branch }
|
||||
continue
|
||||
|
||||
raise cv.Invalid("Invalid component content in package definition")
|
||||
return package_config
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from esphome.components.esp32 import (
|
||||
get_esp32_variant,
|
||||
)
|
||||
from esphome.components.esp32.const import (
|
||||
VARIANT_ESP32C5,
|
||||
VARIANT_ESP32P4,
|
||||
VARIANT_ESP32S2,
|
||||
VARIANT_ESP32S3,
|
||||
@@ -55,6 +56,7 @@ SPIRAM_MODES = {
|
||||
VARIANT_ESP32: (TYPE_QUAD,),
|
||||
VARIANT_ESP32S2: (TYPE_QUAD,),
|
||||
VARIANT_ESP32S3: (TYPE_QUAD, TYPE_OCTAL),
|
||||
VARIANT_ESP32C5: (TYPE_QUAD,),
|
||||
VARIANT_ESP32P4: (TYPE_HEX,),
|
||||
}
|
||||
|
||||
@@ -63,6 +65,7 @@ SPIRAM_SPEEDS = {
|
||||
VARIANT_ESP32: (40, 80, 120),
|
||||
VARIANT_ESP32S2: (40, 80, 120),
|
||||
VARIANT_ESP32S3: (40, 80, 120),
|
||||
VARIANT_ESP32C5: (40, 80, 120),
|
||||
VARIANT_ESP32P4: (20, 100, 200),
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ CONFIG_SCHEMA = remote_base.validate_triggers(
|
||||
bk72xx="1000b",
|
||||
ln882x="1000b",
|
||||
rtl87xx="1000b",
|
||||
rp2040="1000b",
|
||||
): cv.validate_bytes,
|
||||
cv.Optional(CONF_FILTER, default="50us"): cv.All(
|
||||
cv.positive_time_period_microseconds,
|
||||
@@ -213,6 +214,7 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform(
|
||||
PlatformFramework.BK72XX_ARDUINO,
|
||||
PlatformFramework.RTL87XX_ARDUINO,
|
||||
PlatformFramework.LN882X_ARDUINO,
|
||||
PlatformFramework.RP2040_ARDUINO,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#if defined(USE_LIBRETINY) || defined(USE_ESP8266)
|
||||
#if defined(USE_LIBRETINY) || defined(USE_ESP8266) || defined(USE_RP2040)
|
||||
|
||||
namespace esphome {
|
||||
namespace remote_receiver {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user