[text_sensor] Conditionally compile filter infrastructure (#14213)

This commit is contained in:
J. Nick Koston
2026-02-22 21:36:21 -06:00
committed by GitHub
parent 93ce582ad3
commit d239a2400d
6 changed files with 33 additions and 5 deletions

View File

@@ -204,6 +204,7 @@ async def setup_text_sensor_core_(var, config):
cg.add(var.set_device_class(device_class))
if config.get(CONF_FILTERS): # must exist and not be empty
cg.add_define("USE_TEXT_SENSOR_FILTER")
filters = await build_filters(config[CONF_FILTERS])
cg.add(var.set_filters(filters))

View File

@@ -1,3 +1,6 @@
#include "esphome/core/defines.h"
#ifdef USE_TEXT_SENSOR_FILTER
#include "filter.h"
#include "text_sensor.h"
#include "esphome/core/log.h"
@@ -106,3 +109,5 @@ bool MapFilter::new_value(std::string &value) {
} // namespace text_sensor
} // namespace esphome
#endif // USE_TEXT_SENSOR_FILTER

View File

@@ -1,5 +1,8 @@
#pragma once
#include "esphome/core/defines.h"
#ifdef USE_TEXT_SENSOR_FILTER
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
@@ -164,3 +167,5 @@ class MapFilter : public Filter {
} // namespace text_sensor
} // namespace esphome
#endif // USE_TEXT_SENSOR_FILTER

View File

@@ -24,7 +24,9 @@ void TextSensor::publish_state(const std::string &state) { this->publish_state(s
void TextSensor::publish_state(const char *state) { this->publish_state(state, strlen(state)); }
void TextSensor::publish_state(const char *state, size_t len) {
#ifdef USE_TEXT_SENSOR_FILTER
if (this->filter_list_ == nullptr) {
#endif
// No filters: raw_state == state, store once and use for both callbacks
// Only assign if changed to avoid heap allocation
if (len != this->state.size() || memcmp(state, this->state.data(), len) != 0) {
@@ -33,6 +35,7 @@ void TextSensor::publish_state(const char *state, size_t len) {
this->raw_callback_.call(this->state);
ESP_LOGV(TAG, "'%s': Received new state %s", this->name_.c_str(), this->state.c_str());
this->notify_frontend_();
#ifdef USE_TEXT_SENSOR_FILTER
} else {
// Has filters: need separate raw storage
#pragma GCC diagnostic push
@@ -46,8 +49,10 @@ void TextSensor::publish_state(const char *state, size_t len) {
this->filter_list_->input(this->raw_state);
#pragma GCC diagnostic pop
}
#endif
}
#ifdef USE_TEXT_SENSOR_FILTER
void TextSensor::add_filter(Filter *filter) {
// inefficient, but only happens once on every sensor setup and nobody's going to have massive amounts of
// filters
@@ -77,6 +82,7 @@ void TextSensor::clear_filters() {
}
this->filter_list_ = nullptr;
}
#endif // USE_TEXT_SENSOR_FILTER
void TextSensor::add_on_state_callback(std::function<void(const std::string &)> callback) {
this->callback_.add(std::move(callback));
@@ -87,14 +93,16 @@ void TextSensor::add_on_raw_state_callback(std::function<void(const std::string
const std::string &TextSensor::get_state() const { return this->state; }
const std::string &TextSensor::get_raw_state() const {
if (this->filter_list_ == nullptr) {
return this->state; // No filters, raw == filtered
}
// Suppress deprecation warning - get_raw_state() is the replacement API
#ifdef USE_TEXT_SENSOR_FILTER
if (this->filter_list_ != nullptr) {
// Suppress deprecation warning - get_raw_state() is the replacement API
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return this->raw_state;
return this->raw_state;
#pragma GCC diagnostic pop
}
#endif
return this->state; // No filters, raw == filtered
}
void TextSensor::internal_send_state_to_frontend(const std::string &state) {
this->internal_send_state_to_frontend(state.data(), state.size());

View File

@@ -3,7 +3,9 @@
#include "esphome/core/component.h"
#include "esphome/core/entity_base.h"
#include "esphome/core/helpers.h"
#ifdef USE_TEXT_SENSOR_FILTER
#include "esphome/components/text_sensor/filter.h"
#endif
#include <initializer_list>
#include <memory>
@@ -11,6 +13,8 @@
namespace esphome {
namespace text_sensor {
class TextSensor;
void log_text_sensor(const char *tag, const char *prefix, const char *type, TextSensor *obj);
#define LOG_TEXT_SENSOR(prefix, type, obj) log_text_sensor(TAG, prefix, LOG_STR_LITERAL(type), obj)
@@ -45,6 +49,7 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass {
void publish_state(const char *state);
void publish_state(const char *state, size_t len);
#ifdef USE_TEXT_SENSOR_FILTER
/// Add a filter to the filter chain. Will be appended to the back.
void add_filter(Filter *filter);
@@ -56,6 +61,7 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass {
/// Clear the entire filter chain.
void clear_filters();
#endif
void add_on_state_callback(std::function<void(const std::string &)> callback);
/// Add a callback that will be called every time the sensor sends a raw value.
@@ -73,7 +79,9 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass {
LazyCallbackManager<void(const std::string &)> raw_callback_; ///< Storage for raw state callbacks.
LazyCallbackManager<void(const std::string &)> callback_; ///< Storage for filtered state callbacks.
#ifdef USE_TEXT_SENSOR_FILTER
Filter *filter_list_{nullptr}; ///< Store all active filters.
#endif
};
} // namespace text_sensor

View File

@@ -119,6 +119,7 @@
#define USE_SWITCH
#define USE_TEXT
#define USE_TEXT_SENSOR
#define USE_TEXT_SENSOR_FILTER
#define USE_TIME
#define USE_TOUCHSCREEN
#define USE_UART_DEBUGGER