ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
filter.cpp
Go to the documentation of this file.
2#ifdef USE_TEXT_SENSOR_FILTER
3
4#include "filter.h"
5#include "text_sensor.h"
6#include "esphome/core/log.h"
7#include "esphome/core/hal.h"
8
9namespace esphome::text_sensor {
10
11static const char *const TAG = "text_sensor.filter";
12
13// Filter
14void Filter::input(std::string value) {
15 ESP_LOGVV(TAG, "Filter(%p)::input(%s)", this, value.c_str());
16 if (this->new_value(value))
17 this->output(value);
18}
19void Filter::output(std::string &value) {
20 if (this->next_ == nullptr) {
21 ESP_LOGVV(TAG, "Filter(%p)::output(%s) -> SENSOR", this, value.c_str());
23 } else {
24 ESP_LOGVV(TAG, "Filter(%p)::output(%s) -> %p", this, value.c_str(), this->next_);
25 this->next_->input(std::move(value));
26 }
27}
28void Filter::initialize(TextSensor *parent, Filter *next) {
29 ESP_LOGVV(TAG, "Filter(%p)::initialize(parent=%p next=%p)", this, parent, next);
30 this->parent_ = parent;
31 this->next_ = next;
32}
33
34// LambdaFilter
35LambdaFilter::LambdaFilter(lambda_filter_t lambda_filter) : lambda_filter_(std::move(lambda_filter)) {}
37void LambdaFilter::set_lambda_filter(const lambda_filter_t &lambda_filter) { this->lambda_filter_ = lambda_filter; }
38
39bool LambdaFilter::new_value(std::string &value) {
40 auto result = this->lambda_filter_(value);
41 if (result.has_value()) {
42 ESP_LOGVV(TAG, "LambdaFilter(%p)::new_value(%s) -> %s (continue)", this, value.c_str(), result->c_str());
43 value = std::move(*result);
44 return true;
45 }
46 ESP_LOGVV(TAG, "LambdaFilter(%p)::new_value(%s) -> (stop)", this, value.c_str());
47 return false;
48}
49
50// ToUpperFilter
51bool ToUpperFilter::new_value(std::string &value) {
52 for (char &c : value)
53 c = ::toupper(c);
54 return true;
55}
56
57// ToLowerFilter
58bool ToLowerFilter::new_value(std::string &value) {
59 for (char &c : value)
60 c = ::tolower(c);
61 return true;
62}
63
64// Append
65bool AppendFilter::new_value(std::string &value) {
66 value.append(this->suffix_);
67 return true;
68}
69
70// Prepend
71bool PrependFilter::new_value(std::string &value) {
72 value.insert(0, this->prefix_);
73 return true;
74}
75
76// Substitute
77SubstituteFilter::SubstituteFilter(const std::initializer_list<Substitution> &substitutions)
78 : substitutions_(substitutions) {}
79
80bool SubstituteFilter::new_value(std::string &value) {
81 for (const auto &sub : this->substitutions_) {
82 // Compute lengths once per substitution (strlen is fast, called infrequently)
83 const size_t from_len = strlen(sub.from);
84 const size_t to_len = strlen(sub.to);
85 std::size_t pos = 0;
86 while ((pos = value.find(sub.from, pos, from_len)) != std::string::npos) {
87 value.replace(pos, from_len, sub.to, to_len);
88 // Advance past the replacement to avoid infinite loop when
89 // the replacement contains the search pattern (e.g., f -> foo)
90 pos += to_len;
91 }
92 }
93 return true;
94}
95
96// Map
97MapFilter::MapFilter(const std::initializer_list<Substitution> &mappings) : mappings_(mappings) {}
98
99bool MapFilter::new_value(std::string &value) {
100 for (const auto &mapping : this->mappings_) {
101 if (value == mapping.from) {
102 value.assign(mapping.to);
103 return true;
104 }
105 }
106 return true; // Pass through if no match
107}
108
109} // namespace esphome::text_sensor
110
111#endif // USE_TEXT_SENSOR_FILTER
bool new_value(std::string &value) override
Definition filter.cpp:65
Apply a filter to text sensor values such as to_upper.
Definition filter.h:18
virtual bool new_value(std::string &value)=0
This will be called every time the filter receives a new value.
void output(std::string &value)
Definition filter.cpp:19
void input(std::string value)
Definition filter.cpp:14
virtual void initialize(TextSensor *parent, Filter *next)
Initialize this filter, please note this can be called more than once.
Definition filter.cpp:28
lambda_filter_t lambda_filter_
Definition filter.h:62
LambdaFilter(lambda_filter_t lambda_filter)
Definition filter.cpp:35
void set_lambda_filter(const lambda_filter_t &lambda_filter)
Definition filter.cpp:37
bool new_value(std::string &value) override
Definition filter.cpp:39
const lambda_filter_t & get_lambda_filter() const
Definition filter.cpp:36
bool new_value(std::string &value) override
Definition filter.cpp:99
MapFilter(const std::initializer_list< Substitution > &mappings)
Definition filter.cpp:97
FixedVector< Substitution > mappings_
Definition filter.h:164
bool new_value(std::string &value) override
Definition filter.cpp:71
FixedVector< Substitution > substitutions_
Definition filter.h:131
bool new_value(std::string &value) override
Definition filter.cpp:80
SubstituteFilter(const std::initializer_list< Substitution > &substitutions)
Definition filter.cpp:77
void internal_send_state_to_frontend(const std::string &state)
bool new_value(std::string &value) override
Definition filter.cpp:58
bool new_value(std::string &value) override
Definition filter.cpp:51
const char *const TAG
Definition spi.cpp:7
std::function< optional< std::string >(std::string)> lambda_filter_t
Definition filter.h:44
size_t size_t pos
Definition helpers.h:854