#pragma once #include "esphome/core/component.h" #include "esphome/core/preferences.h" #include "esphome/core/automation.h" #include "esphome/core/hal.h" #include "esphome/components/sensor/sensor.h" namespace esphome { namespace integration { enum IntegrationSensorTime { INTEGRATION_SENSOR_TIME_MILLISECOND = 0, INTEGRATION_SENSOR_TIME_SECOND, INTEGRATION_SENSOR_TIME_MINUTE, INTEGRATION_SENSOR_TIME_HOUR, INTEGRATION_SENSOR_TIME_DAY, }; enum IntegrationMethod { INTEGRATION_METHOD_TRAPEZOID = 0, INTEGRATION_METHOD_LEFT, INTEGRATION_METHOD_RIGHT, }; class IntegrationSensor : public sensor::Sensor, public Component { public: void setup() override; void dump_config() override; float get_setup_priority() const override { return setup_priority::DATA; } void set_min_save_interval(uint32_t min_interval) { this->min_save_interval_ = min_interval; } void set_sensor(Sensor *sensor) { sensor_ = sensor; } void set_time(IntegrationSensorTime time) { time_ = time; } void set_method(IntegrationMethod method) { method_ = method; } void set_restore(bool restore) { restore_ = restore; } void reset() { this->publish_and_save_(0.0f); } protected: void process_sensor_value_(float value); float get_time_factor_() { switch (this->time_) { case INTEGRATION_SENSOR_TIME_MILLISECOND: return 1.0f; case INTEGRATION_SENSOR_TIME_SECOND: return 1.0f / 1000.0f; case INTEGRATION_SENSOR_TIME_MINUTE: return 1.0f / 60000.0f; case INTEGRATION_SENSOR_TIME_HOUR: return 1.0f / 3600000.0f; case INTEGRATION_SENSOR_TIME_DAY: return 1.0f / 86400000.0f; default: return 0.0f; } } void publish_and_save_(double result) { this->result_ = result; this->publish_state(result); float result_f = result; const uint32_t now = millis(); if (now - this->last_save_ < this->min_save_interval_) return; this->last_save_ = now; this->rtc_.save(&result_f); } std::string unit_of_measurement() override; int8_t accuracy_decimals() override { return this->sensor_->get_accuracy_decimals() + 2; } sensor::Sensor *sensor_; IntegrationSensorTime time_; IntegrationMethod method_; bool restore_; ESPPreferenceObject rtc_; uint32_t last_save_{0}; uint32_t min_save_interval_{0}; uint32_t last_update_; double result_{0.0f}; float last_value_{0.0f}; }; template class ResetAction : public Action { public: explicit ResetAction(IntegrationSensor *parent) : parent_(parent) {} void play(Ts... x) override { this->parent_->reset(); } protected: IntegrationSensor *parent_; }; } // namespace integration } // namespace esphome