12static constexpr uint32_t NEW_VALUE_DEFER_ID = 0;
15 LOG_SENSOR(
"",
"Combination Sensor:",
this);
16 ESP_LOGCONFIG(TAG,
" Combination Type: %s", LOG_STR_ARG(combo_type));
27 this->
add_source(sensor, std::function<
float(
float)>{[value](
float x) ->
float {
return value; }});
31 ESP_LOGCONFIG(TAG,
" Source Sensors:");
32 for (
const auto &sensor : this->
sensors_) {
33 ESP_LOGCONFIG(TAG,
" - %s", LOG_STR_ARG(sensor->get_log_name()));
38 ESP_LOGCONFIG(TAG,
" Source Sensors:");
40 ESP_LOGCONFIG(TAG,
" - %s", LOG_STR_ARG(source.sensor->get_log_name()));
45 for (
const auto &sensor : this->
sensors_) {
48 sensor->add_on_state_callback([
this](
float value) ->
void {
67 source.sensor->add_on_state_callback([&source](
float x) ->
void {
80 this->last_update_ = now;
84 if (std::isnan(value) || std::isinf(stddev)) {
101 const bool this_first = this->
variance_ < (stddev * stddev);
102 const float mu1 = this_first ? this->
state_ : value;
103 const float mu2 = this_first ? value : this->
state_;
105 const float var1 = this_first ? this->
variance_ : stddev * stddev;
106 const float var2 = this_first ? stddev * stddev : this->
variance_;
108 const float mu = mu1 + var1 * (mu2 - mu1) / (var1 + var2);
109 const float var = var1 - (var1 * var1) / (var1 + var2);
125 source.sensor->add_on_state_callback([
this](
float value) ->
void {
134 if (!std::isfinite(value))
140 const float sensor_state = source.sensor->state;
141 if (std::isfinite(sensor_state)) {
142 sum += sensor_state * source.compute(sensor_state);
150 if (!std::isfinite(value))
153 float max_value = (-1) * std::numeric_limits<float>::infinity();
155 for (
const auto &sensor : this->
sensors_) {
156 if (std::isfinite(sensor->state)) {
157 max_value = std::max(max_value, sensor->state);
165 if (!std::isfinite(value))
171 for (
const auto &sensor : this->
sensors_) {
172 if (std::isfinite(sensor->state)) {
174 sum += sensor->state;
182 float mean = sum /
count;
190 if (!std::isfinite(value))
193 std::vector<float> sensor_states;
194 for (
const auto &sensor : this->
sensors_) {
195 if (std::isfinite(sensor->state)) {
196 sensor_states.push_back(sensor->state);
200 sort(sensor_states.begin(), sensor_states.end());
201 size_t sensor_states_size = sensor_states.size();
205 if (sensor_states_size) {
206 if (sensor_states_size % 2) {
208 median = sensor_states[sensor_states_size / 2];
211 median = (sensor_states[sensor_states_size / 2] + sensor_states[sensor_states_size / 2 - 1]) / 2.0f;
219 if (!std::isfinite(value))
222 float min_value = std::numeric_limits<float>::infinity();
224 for (
const auto &sensor : this->
sensors_) {
225 if (std::isfinite(sensor->state)) {
226 min_value = std::min(min_value, sensor->state);
238 if (!std::isfinite(value))
241 std::vector<float> sensor_states;
242 for (
const auto &sensor : this->
sensors_) {
243 if (std::isfinite(sensor->state)) {
244 sensor_states.push_back(sensor->state);
248 if (sensor_states.empty()) {
253 sort(sensor_states.begin(), sensor_states.end());
255 float range = sensor_states.back() - sensor_states.front();
260 if (!std::isfinite(value))
264 for (
const auto &sensor : this->
sensors_) {
265 if (std::isfinite(sensor->state)) {
266 sum += sensor->state;
void defer(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call with a const char* name.
void log_config_(const LogString *combo_type)
Logs the sensor for use in dump_config.
virtual void log_source_sensors()=0
Logs all source sensor's names.
std::vector< Sensor * > sensors_
void setup() override
Adds a callback to each source sensor.
virtual void handle_new_value(float value)=0
Computes the combination.
void log_source_sensors() override
Logs all source sensor's names in sensors_.
void add_source(Sensor *sensor)
FixedVector< SensorSource > sensor_sources_
void log_source_sensors() override
Logs all source sensors' names in sensor_sources_.
void add_source(Sensor *sensor, std::function< float(float)> const &compute)
float update_variance_value_
void correct_(float value, float stddev)
sensor::Sensor * std_dev_sensor_
void dump_config() override
void handle_new_value(float value)
void handle_new_value(float value) override
void handle_new_value(float value) override
void handle_new_value(float value) override
void handle_new_value(float value) override
void handle_new_value(float value) override
void handle_new_value(float value) override
void publish_state(float state)
Publish a new state to the front-end.
ESPHOME_LOG_TAG(TAG, "combination")
uint32_t IRAM_ATTR HOT millis()