ESPHome 2026.1.3
Loading...
Searching...
No Matches
text_sensor.cpp
Go to the documentation of this file.
1#include "text_sensor.h"
4#include "esphome/core/log.h"
5#include <cstring>
6
7namespace esphome {
8namespace text_sensor {
9
10static const char *const TAG = "text_sensor";
11
12void log_text_sensor(const char *tag, const char *prefix, const char *type, TextSensor *obj) {
13 if (obj == nullptr) {
14 return;
15 }
16
17 ESP_LOGCONFIG(tag, "%s%s '%s'", prefix, type, obj->get_name().c_str());
18
19 if (!obj->get_device_class_ref().empty()) {
20 ESP_LOGCONFIG(tag, "%s Device Class: '%s'", prefix, obj->get_device_class_ref().c_str());
21 }
22
23 if (!obj->get_icon_ref().empty()) {
24 ESP_LOGCONFIG(tag, "%s Icon: '%s'", prefix, obj->get_icon_ref().c_str());
25 }
26}
27
28void TextSensor::publish_state(const std::string &state) { this->publish_state(state.data(), state.size()); }
29
30void TextSensor::publish_state(const char *state) { this->publish_state(state, strlen(state)); }
31
32void TextSensor::publish_state(const char *state, size_t len) {
33 if (this->filter_list_ == nullptr) {
34 // No filters: raw_state == state, store once and use for both callbacks
35 // Only assign if changed to avoid heap allocation
36 if (len != this->state.size() || memcmp(state, this->state.data(), len) != 0) {
37 this->state.assign(state, len);
38 }
39 this->raw_callback_.call(this->state);
40 ESP_LOGV(TAG, "'%s': Received new state %s", this->name_.c_str(), this->state.c_str());
41 this->notify_frontend_();
42 } else {
43 // Has filters: need separate raw storage
44#pragma GCC diagnostic push
45#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
46 // Only assign if changed to avoid heap allocation
47 if (len != this->raw_state.size() || memcmp(state, this->raw_state.data(), len) != 0) {
48 this->raw_state.assign(state, len);
49 }
50 this->raw_callback_.call(this->raw_state);
51 ESP_LOGV(TAG, "'%s': Received new state %s", this->name_.c_str(), this->raw_state.c_str());
52 this->filter_list_->input(this->raw_state);
53#pragma GCC diagnostic pop
54 }
55}
56
58 // inefficient, but only happens once on every sensor setup and nobody's going to have massive amounts of
59 // filters
60 ESP_LOGVV(TAG, "TextSensor(%p)::add_filter(%p)", this, filter);
61 if (this->filter_list_ == nullptr) {
62 this->filter_list_ = filter;
63 } else {
64 Filter *last_filter = this->filter_list_;
65 while (last_filter->next_ != nullptr)
66 last_filter = last_filter->next_;
67 last_filter->initialize(this, filter);
68 }
69 filter->initialize(this, nullptr);
70}
71void TextSensor::add_filters(std::initializer_list<Filter *> filters) {
72 for (Filter *filter : filters) {
73 this->add_filter(filter);
74 }
75}
76void TextSensor::set_filters(std::initializer_list<Filter *> filters) {
77 this->clear_filters();
78 this->add_filters(filters);
79}
81 if (this->filter_list_ != nullptr) {
82 ESP_LOGVV(TAG, "TextSensor(%p)::clear_filters()", this);
83 }
84 this->filter_list_ = nullptr;
85}
86
87void TextSensor::add_on_state_callback(std::function<void(const std::string &)> callback) {
88 this->callback_.add(std::move(callback));
89}
90void TextSensor::add_on_raw_state_callback(std::function<void(const std::string &)> callback) {
91 this->raw_callback_.add(std::move(callback));
92}
93
94const std::string &TextSensor::get_state() const { return this->state; }
95const std::string &TextSensor::get_raw_state() const {
96 if (this->filter_list_ == nullptr) {
97 return this->state; // No filters, raw == filtered
98 }
99// Suppress deprecation warning - get_raw_state() is the replacement API
100#pragma GCC diagnostic push
101#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
102 return this->raw_state;
103#pragma GCC diagnostic pop
104}
106 this->internal_send_state_to_frontend(state.data(), state.size());
107}
108
110 // Only assign if changed to avoid heap allocation
111 if (len != this->state.size() || memcmp(state, this->state.data(), len) != 0) {
112 this->state.assign(state, len);
113 }
114 this->notify_frontend_();
115}
116
118 this->set_has_state(true);
119 ESP_LOGD(TAG, "'%s' >> '%s'", this->name_.c_str(), this->state.c_str());
120 this->callback_.call(this->state);
121#if defined(USE_TEXT_SENSOR) && defined(USE_CONTROLLER_REGISTRY)
123#endif
124}
125
126} // namespace text_sensor
127} // namespace esphome
static void notify_text_sensor_update(text_sensor::TextSensor *obj)
StringRef get_device_class_ref() const
Get the device class as StringRef.
const StringRef & get_name() const
StringRef get_icon_ref() const
Definition entity_base.h:97
void set_has_state(bool state)
constexpr const char * c_str() const
Definition string_ref.h:73
constexpr bool empty() const
Definition string_ref.h:75
Apply a filter to text sensor values such as to_upper.
Definition filter.h:16
void input(const 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:27
void internal_send_state_to_frontend(const std::string &state)
void add_filter(Filter *filter)
Add a filter to the filter chain. Will be appended to the back.
const std::string & get_raw_state() const
Getter-syntax for .raw_state.
void add_on_state_callback(std::function< void(const std::string &)> callback)
void clear_filters()
Clear the entire filter chain.
void set_filters(std::initializer_list< Filter * > filters)
Clear the filters and replace them by filters.
Filter * filter_list_
Store all active filters.
Definition text_sensor.h:76
LazyCallbackManager< void(const std::string &)> raw_callback_
Storage for raw state callbacks.
Definition text_sensor.h:73
LazyCallbackManager< void(const std::string &)> callback_
Storage for filtered state callbacks.
Definition text_sensor.h:74
void add_on_raw_state_callback(std::function< void(const std::string &)> callback)
Add a callback that will be called every time the sensor sends a raw value.
const std::string & get_state() const
Getter-syntax for .state.
void add_filters(std::initializer_list< Filter * > filters)
Add a list of vectors to the back of the filter chain.
void notify_frontend_()
Notify frontend that state has changed (assumes this->state is already set)
void publish_state(const std::string &state)
uint16_t type
bool state
Definition fan.h:0
const char *const TAG
Definition spi.cpp:7
void log_text_sensor(const char *tag, const char *prefix, const char *type, TextSensor *obj)
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:595