ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
sensor.cpp
Go to the documentation of this file.
1#include "sensor.h"
4#include "esphome/core/log.h"
6
7namespace esphome::sensor {
8
9static const char *const TAG = "sensor";
10
11// Function implementation of LOG_SENSOR macro to reduce code size
12void log_sensor(const char *tag, const char *prefix, const char *type, Sensor *obj) {
13 if (obj == nullptr) {
14 return;
15 }
16
17 ESP_LOGCONFIG(tag,
18 "%s%s '%s'\n"
19 "%s State Class: '%s'\n"
20 "%s Unit of Measurement: '%s'\n"
21 "%s Accuracy Decimals: %d",
22 prefix, type, obj->get_name().c_str(), prefix,
23 LOG_STR_ARG(state_class_to_string(obj->get_state_class())), prefix,
25
26 LOG_ENTITY_DEVICE_CLASS(tag, prefix, *obj);
27 LOG_ENTITY_ICON(tag, prefix, *obj);
28
29 if (obj->get_force_update()) {
30 ESP_LOGV(tag, "%s Force Update: YES", prefix);
31 }
32}
33
34// State class strings indexed by StateClass enum (0-4): NONE, MEASUREMENT, TOTAL_INCREASING, TOTAL, MEASUREMENT_ANGLE
35PROGMEM_STRING_TABLE(StateClassStrings, "", "measurement", "total_increasing", "total", "measurement_angle");
36static_assert(StateClassStrings::COUNT == STATE_CLASS_LAST + 1, "StateClassStrings must match StateClass enum");
37
38const LogString *state_class_to_string(StateClass state_class) {
39 // Fallback to index 0 (empty string for STATE_CLASS_NONE) if out of range
40 return StateClassStrings::get_log_str(static_cast<uint8_t>(state_class), 0);
41}
42
43Sensor::Sensor() : state(NAN), raw_state(NAN) {}
44
47 return this->accuracy_decimals_;
48 return 0;
49}
50void Sensor::set_accuracy_decimals(int8_t accuracy_decimals) {
51 this->accuracy_decimals_ = accuracy_decimals;
53}
54
56 this->state_class_ = state_class;
58}
64
66 this->raw_state = state;
67 this->raw_callback_.call(state);
68
69 ESP_LOGV(TAG, "'%s': Received new state %f", this->name_.c_str(), state);
70
71#ifdef USE_SENSOR_FILTER
72 if (this->filter_list_ == nullptr) {
73#endif
75#ifdef USE_SENSOR_FILTER
76 } else {
77 this->filter_list_->input(state);
78 }
79#endif
80}
81
82void Sensor::add_on_state_callback(std::function<void(float)> &&callback) { this->callback_.add(std::move(callback)); }
83void Sensor::add_on_raw_state_callback(std::function<void(float)> &&callback) {
84 this->raw_callback_.add(std::move(callback));
85}
86
87#ifdef USE_SENSOR_FILTER
89 // inefficient, but only happens once on every sensor setup and nobody's going to have massive amounts of
90 // filters
91 ESP_LOGVV(TAG, "Sensor(%p)::add_filter(%p)", this, filter);
92 if (this->filter_list_ == nullptr) {
93 this->filter_list_ = filter;
94 } else {
95 Filter *last_filter = this->filter_list_;
96 while (last_filter->next_ != nullptr)
97 last_filter = last_filter->next_;
98 last_filter->initialize(this, filter);
99 }
100 filter->initialize(this, nullptr);
101}
102void Sensor::add_filters(std::initializer_list<Filter *> filters) {
103 for (Filter *filter : filters) {
104 this->add_filter(filter);
105 }
106}
107void Sensor::set_filters(std::initializer_list<Filter *> filters) {
108 this->clear_filters();
109 this->add_filters(filters);
110}
112 if (this->filter_list_ != nullptr) {
113 ESP_LOGVV(TAG, "Sensor(%p)::clear_filters()", this);
114 }
115 this->filter_list_ = nullptr;
116}
117#endif // USE_SENSOR_FILTER
118float Sensor::get_state() const { return this->state; }
119float Sensor::get_raw_state() const { return this->raw_state; }
120
122 this->set_has_state(true);
123 this->state = state;
124 ESP_LOGD(TAG, "'%s' >> %.*f %s", this->get_name().c_str(), std::max(0, (int) this->get_accuracy_decimals()), state,
125 this->get_unit_of_measurement_ref().c_str());
126 this->callback_.call(state);
127#if defined(USE_SENSOR) && defined(USE_CONTROLLER_REGISTRY)
129#endif
130}
131
132} // namespace esphome::sensor
static void notify_sensor_update(sensor::Sensor *obj)
StringRef get_unit_of_measurement_ref() const
Get the unit of measurement as StringRef.
const StringRef & get_name() const
void set_has_state(bool state)
constexpr const char * c_str() const
Definition string_ref.h:73
Apply a filter to sensor values such as moving average.
Definition filter.h:21
virtual void initialize(Sensor *parent, Filter *next)
Initialize this filter, please note this can be called more than once.
Definition filter.cpp:37
void input(float value)
Definition filter.cpp:22
Base-class for all sensors.
Definition sensor.h:47
void set_state_class(StateClass state_class)
Manually set the state class.
Definition sensor.cpp:55
void add_filter(Filter *filter)
Add a filter to the filter chain. Will be appended to the back.
Definition sensor.cpp:88
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:65
LazyCallbackManager< void(float)> callback_
Storage for filtered state callbacks.
Definition sensor.h:137
void internal_send_state_to_frontend(float state)
Definition sensor.cpp:121
float get_raw_state() const
Getter-syntax for .raw_state.
Definition sensor.cpp:119
float get_state() const
Getter-syntax for .state.
Definition sensor.cpp:118
void set_accuracy_decimals(int8_t accuracy_decimals)
Manually set the accuracy in decimals.
Definition sensor.cpp:50
void add_on_state_callback(std::function< void(float)> &&callback)
Add a callback that will be called every time a filtered value arrives.
Definition sensor.cpp:82
float state
This member variable stores the last state that has passed through all filters.
Definition sensor.h:125
StateClass get_state_class()
Get the state class, using the manual override if set.
Definition sensor.cpp:59
Filter * filter_list_
Store all active filters.
Definition sensor.h:140
float raw_state
This member variable stores the current raw state of the sensor, without any filters applied.
Definition sensor.h:131
LazyCallbackManager< void(float)> raw_callback_
Storage for raw state callbacks.
Definition sensor.h:136
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
Definition sensor.cpp:45
void clear_filters()
Clear the entire filter chain.
Definition sensor.cpp:111
int8_t accuracy_decimals_
Accuracy in decimals (-1 = not set)
Definition sensor.h:144
StateClass state_class_
State class (STATE_CLASS_NONE = not set)
Definition sensor.h:145
bool get_force_update() const
Get whether force update mode is enabled.
Definition sensor.h:70
struct esphome::sensor::Sensor::SensorFlags sensor_flags_
void add_on_raw_state_callback(std::function< void(float)> &&callback)
Add a callback that will be called every time the sensor sends a raw value.
Definition sensor.cpp:83
void set_filters(std::initializer_list< Filter * > filters)
Clear the filters and replace them by filters.
Definition sensor.cpp:107
void add_filters(std::initializer_list< Filter * > filters)
Add a list of vectors to the back of the filter chain.
Definition sensor.cpp:102
uint16_t type
bool state
Definition fan.h:2
constexpr uint8_t STATE_CLASS_LAST
Definition sensor.h:39
PROGMEM_STRING_TABLE(StateClassStrings, "", "measurement", "total_increasing", "total", "measurement_angle")
StateClass
Sensor state classes.
Definition sensor.h:32
void log_sensor(const char *tag, const char *prefix, const char *type, Sensor *obj)
Definition sensor.cpp:12
const LogString * state_class_to_string(StateClass state_class)
Definition sensor.cpp:38