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