mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Clean-up sensor integration (#2275)
This commit is contained in:
		
				
					committed by
					
						 Jesse Hills
						Jesse Hills
					
				
			
			
				
	
			
			
			
						parent
						
							954b8a0cff
						
					
				
				
					commit
					8bda8e5393
				
			| @@ -422,7 +422,7 @@ bool APIConnection::send_sensor_info(sensor::Sensor *sensor) { | |||||||
|   msg.accuracy_decimals = sensor->get_accuracy_decimals(); |   msg.accuracy_decimals = sensor->get_accuracy_decimals(); | ||||||
|   msg.force_update = sensor->get_force_update(); |   msg.force_update = sensor->get_force_update(); | ||||||
|   msg.device_class = sensor->get_device_class(); |   msg.device_class = sensor->get_device_class(); | ||||||
|   msg.state_class = static_cast<enums::SensorStateClass>(sensor->state_class); |   msg.state_class = static_cast<enums::SensorStateClass>(sensor->get_state_class()); | ||||||
|   msg.disabled_by_default = sensor->is_disabled_by_default(); |   msg.disabled_by_default = sensor->is_disabled_by_default(); | ||||||
|  |  | ||||||
|   return this->send_list_entities_sensor_response(msg); |   return this->send_list_entities_sensor_response(msg); | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ class DemoSensor : public sensor::Sensor, public PollingComponent { | |||||||
|  public: |  public: | ||||||
|   void update() override { |   void update() override { | ||||||
|     float val = random_float(); |     float val = random_float(); | ||||||
|     bool increasing = this->state_class == sensor::STATE_CLASS_TOTAL_INCREASING; |     bool increasing = this->get_state_class() == sensor::STATE_CLASS_TOTAL_INCREASING; | ||||||
|     if (increasing) { |     if (increasing) { | ||||||
|       float base = isnan(this->state) ? 0.0f : this->state; |       float base = isnan(this->state) ? 0.0f : this->state; | ||||||
|       this->publish_state(base + val * 10); |       this->publish_state(base + val * 10); | ||||||
|   | |||||||
| @@ -31,16 +31,9 @@ void MQTTSensorComponent::dump_config() { | |||||||
| std::string MQTTSensorComponent::component_type() const { return "sensor"; } | std::string MQTTSensorComponent::component_type() const { return "sensor"; } | ||||||
|  |  | ||||||
| uint32_t MQTTSensorComponent::get_expire_after() const { | uint32_t MQTTSensorComponent::get_expire_after() const { | ||||||
|   if (this->expire_after_.has_value()) { |   if (this->expire_after_.has_value()) | ||||||
|     return *this->expire_after_; |     return *this->expire_after_; | ||||||
|   } else { |   return 0; | ||||||
| #ifdef USE_DEEP_SLEEP |  | ||||||
|     if (deep_sleep::global_has_deep_sleep) { |  | ||||||
|       return 0; |  | ||||||
|     } |  | ||||||
| #endif |  | ||||||
|     return this->sensor_->calculate_expected_filter_update_interval() * 5; |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| void MQTTSensorComponent::set_expire_after(uint32_t expire_after) { this->expire_after_ = expire_after; } | void MQTTSensorComponent::set_expire_after(uint32_t expire_after) { this->expire_after_ = expire_after; } | ||||||
| void MQTTSensorComponent::disable_expire_after() { this->expire_after_ = 0; } | void MQTTSensorComponent::disable_expire_after() { this->expire_after_ = 0; } | ||||||
| @@ -61,8 +54,8 @@ void MQTTSensorComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryCo | |||||||
|   if (this->sensor_->get_force_update()) |   if (this->sensor_->get_force_update()) | ||||||
|     root["force_update"] = true; |     root["force_update"] = true; | ||||||
|  |  | ||||||
|   if (this->sensor_->state_class != STATE_CLASS_NONE) |   if (this->sensor_->get_state_class() != STATE_CLASS_NONE) | ||||||
|     root["state_class"] = state_class_to_string(this->sensor_->state_class); |     root["state_class"] = state_class_to_string(this->sensor_->get_state_class()); | ||||||
|  |  | ||||||
|   config.command_topic = false; |   config.command_topic = false; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ namespace sensor { | |||||||
| static const char *const TAG = "sensor.filter"; | static const char *const TAG = "sensor.filter"; | ||||||
|  |  | ||||||
| // Filter | // Filter | ||||||
| uint32_t Filter::expected_interval(uint32_t input) { return input; } |  | ||||||
| void Filter::input(float value) { | void Filter::input(float value) { | ||||||
|   ESP_LOGVV(TAG, "Filter(%p)::input(%f)", this, value); |   ESP_LOGVV(TAG, "Filter(%p)::input(%f)", this, value); | ||||||
|   optional<float> out = this->new_value(value); |   optional<float> out = this->new_value(value); | ||||||
| @@ -29,15 +28,6 @@ void Filter::initialize(Sensor *parent, Filter *next) { | |||||||
|   this->parent_ = parent; |   this->parent_ = parent; | ||||||
|   this->next_ = next; |   this->next_ = next; | ||||||
| } | } | ||||||
| uint32_t Filter::calculate_remaining_interval(uint32_t input) { |  | ||||||
|   uint32_t this_interval = this->expected_interval(input); |  | ||||||
|   ESP_LOGVV(TAG, "Filter(%p)::calculate_remaining_interval(%u) -> %u", this, input, this_interval); |  | ||||||
|   if (this->next_ == nullptr) { |  | ||||||
|     return this_interval; |  | ||||||
|   } else { |  | ||||||
|     return this->next_->calculate_remaining_interval(this_interval); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // MedianFilter | // MedianFilter | ||||||
| MedianFilter::MedianFilter(size_t window_size, size_t send_every, size_t send_first_at) | MedianFilter::MedianFilter(size_t window_size, size_t send_every, size_t send_first_at) | ||||||
| @@ -75,8 +65,6 @@ optional<float> MedianFilter::new_value(float value) { | |||||||
|   return {}; |   return {}; | ||||||
| } | } | ||||||
|  |  | ||||||
| uint32_t MedianFilter::expected_interval(uint32_t input) { return input * this->send_every_; } |  | ||||||
|  |  | ||||||
| // MinFilter | // MinFilter | ||||||
| MinFilter::MinFilter(size_t window_size, size_t send_every, size_t send_first_at) | MinFilter::MinFilter(size_t window_size, size_t send_every, size_t send_first_at) | ||||||
|     : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {} |     : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {} | ||||||
| @@ -106,8 +94,6 @@ optional<float> MinFilter::new_value(float value) { | |||||||
|   return {}; |   return {}; | ||||||
| } | } | ||||||
|  |  | ||||||
| uint32_t MinFilter::expected_interval(uint32_t input) { return input * this->send_every_; } |  | ||||||
|  |  | ||||||
| // MaxFilter | // MaxFilter | ||||||
| MaxFilter::MaxFilter(size_t window_size, size_t send_every, size_t send_first_at) | MaxFilter::MaxFilter(size_t window_size, size_t send_every, size_t send_first_at) | ||||||
|     : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {} |     : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {} | ||||||
| @@ -137,8 +123,6 @@ optional<float> MaxFilter::new_value(float value) { | |||||||
|   return {}; |   return {}; | ||||||
| } | } | ||||||
|  |  | ||||||
| uint32_t MaxFilter::expected_interval(uint32_t input) { return input * this->send_every_; } |  | ||||||
|  |  | ||||||
| // SlidingWindowMovingAverageFilter | // SlidingWindowMovingAverageFilter | ||||||
| SlidingWindowMovingAverageFilter::SlidingWindowMovingAverageFilter(size_t window_size, size_t send_every, | SlidingWindowMovingAverageFilter::SlidingWindowMovingAverageFilter(size_t window_size, size_t send_every, | ||||||
|                                                                    size_t send_first_at) |                                                                    size_t send_first_at) | ||||||
| @@ -177,8 +161,6 @@ optional<float> SlidingWindowMovingAverageFilter::new_value(float value) { | |||||||
|   return {}; |   return {}; | ||||||
| } | } | ||||||
|  |  | ||||||
| uint32_t SlidingWindowMovingAverageFilter::expected_interval(uint32_t input) { return input * this->send_every_; } |  | ||||||
|  |  | ||||||
| // ExponentialMovingAverageFilter | // ExponentialMovingAverageFilter | ||||||
| ExponentialMovingAverageFilter::ExponentialMovingAverageFilter(float alpha, size_t send_every) | ExponentialMovingAverageFilter::ExponentialMovingAverageFilter(float alpha, size_t send_every) | ||||||
|     : send_every_(send_every), send_at_(send_every - 1), alpha_(alpha) {} |     : send_every_(send_every), send_at_(send_every - 1), alpha_(alpha) {} | ||||||
| @@ -203,7 +185,6 @@ optional<float> ExponentialMovingAverageFilter::new_value(float value) { | |||||||
| } | } | ||||||
| void ExponentialMovingAverageFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; } | void ExponentialMovingAverageFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; } | ||||||
| void ExponentialMovingAverageFilter::set_alpha(float alpha) { this->alpha_ = alpha; } | void ExponentialMovingAverageFilter::set_alpha(float alpha) { this->alpha_ = alpha; } | ||||||
| uint32_t ExponentialMovingAverageFilter::expected_interval(uint32_t input) { return input * this->send_every_; } |  | ||||||
|  |  | ||||||
| // LambdaFilter | // LambdaFilter | ||||||
| LambdaFilter::LambdaFilter(lambda_filter_t lambda_filter) : lambda_filter_(std::move(lambda_filter)) {} | LambdaFilter::LambdaFilter(lambda_filter_t lambda_filter) : lambda_filter_(std::move(lambda_filter)) {} | ||||||
| @@ -296,14 +277,6 @@ void OrFilter::initialize(Sensor *parent, Filter *next) { | |||||||
|   this->phi_.initialize(parent, nullptr); |   this->phi_.initialize(parent, nullptr); | ||||||
| } | } | ||||||
|  |  | ||||||
| uint32_t OrFilter::expected_interval(uint32_t input) { |  | ||||||
|   uint32_t min_interval = UINT32_MAX; |  | ||||||
|   for (Filter *filter : this->filters_) { |  | ||||||
|     min_interval = std::min(min_interval, filter->calculate_remaining_interval(input)); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return min_interval; |  | ||||||
| } |  | ||||||
| // DebounceFilter | // DebounceFilter | ||||||
| optional<float> DebounceFilter::new_value(float value) { | optional<float> DebounceFilter::new_value(float value) { | ||||||
|   this->set_timeout("debounce", this->time_period_, [this, value]() { this->output(value); }); |   this->set_timeout("debounce", this->time_period_, [this, value]() { this->output(value); }); | ||||||
| @@ -324,7 +297,6 @@ optional<float> HeartbeatFilter::new_value(float value) { | |||||||
|  |  | ||||||
|   return {}; |   return {}; | ||||||
| } | } | ||||||
| uint32_t HeartbeatFilter::expected_interval(uint32_t input) { return this->time_period_; } |  | ||||||
| void HeartbeatFilter::setup() { | void HeartbeatFilter::setup() { | ||||||
|   this->set_interval("heartbeat", this->time_period_, [this]() { |   this->set_interval("heartbeat", this->time_period_, [this]() { | ||||||
|     ESP_LOGVV(TAG, "HeartbeatFilter(%p)::interval(has_value=%s, last_input=%f)", this, YESNO(this->has_value_), |     ESP_LOGVV(TAG, "HeartbeatFilter(%p)::interval(has_value=%s, last_input=%f)", this, YESNO(this->has_value_), | ||||||
|   | |||||||
| @@ -33,11 +33,6 @@ class Filter { | |||||||
|  |  | ||||||
|   void input(float value); |   void input(float value); | ||||||
|  |  | ||||||
|   /// Return the amount of time that this filter is expected to take based on the input time interval. |  | ||||||
|   virtual uint32_t expected_interval(uint32_t input); |  | ||||||
|  |  | ||||||
|   uint32_t calculate_remaining_interval(uint32_t input); |  | ||||||
|  |  | ||||||
|   void output(float value); |   void output(float value); | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
| @@ -68,8 +63,6 @@ class MedianFilter : public Filter { | |||||||
|   void set_send_every(size_t send_every); |   void set_send_every(size_t send_every); | ||||||
|   void set_window_size(size_t window_size); |   void set_window_size(size_t window_size); | ||||||
|  |  | ||||||
|   uint32_t expected_interval(uint32_t input) override; |  | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   std::deque<float> queue_; |   std::deque<float> queue_; | ||||||
|   size_t send_every_; |   size_t send_every_; | ||||||
| @@ -98,8 +91,6 @@ class MinFilter : public Filter { | |||||||
|   void set_send_every(size_t send_every); |   void set_send_every(size_t send_every); | ||||||
|   void set_window_size(size_t window_size); |   void set_window_size(size_t window_size); | ||||||
|  |  | ||||||
|   uint32_t expected_interval(uint32_t input) override; |  | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   std::deque<float> queue_; |   std::deque<float> queue_; | ||||||
|   size_t send_every_; |   size_t send_every_; | ||||||
| @@ -128,8 +119,6 @@ class MaxFilter : public Filter { | |||||||
|   void set_send_every(size_t send_every); |   void set_send_every(size_t send_every); | ||||||
|   void set_window_size(size_t window_size); |   void set_window_size(size_t window_size); | ||||||
|  |  | ||||||
|   uint32_t expected_interval(uint32_t input) override; |  | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   std::deque<float> queue_; |   std::deque<float> queue_; | ||||||
|   size_t send_every_; |   size_t send_every_; | ||||||
| @@ -159,8 +148,6 @@ class SlidingWindowMovingAverageFilter : public Filter { | |||||||
|   void set_send_every(size_t send_every); |   void set_send_every(size_t send_every); | ||||||
|   void set_window_size(size_t window_size); |   void set_window_size(size_t window_size); | ||||||
|  |  | ||||||
|   uint32_t expected_interval(uint32_t input) override; |  | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   float sum_{0.0}; |   float sum_{0.0}; | ||||||
|   std::deque<float> queue_; |   std::deque<float> queue_; | ||||||
| @@ -183,8 +170,6 @@ class ExponentialMovingAverageFilter : public Filter { | |||||||
|   void set_send_every(size_t send_every); |   void set_send_every(size_t send_every); | ||||||
|   void set_alpha(float alpha); |   void set_alpha(float alpha); | ||||||
|  |  | ||||||
|   uint32_t expected_interval(uint32_t input) override; |  | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   bool first_value_{true}; |   bool first_value_{true}; | ||||||
|   float accumulator_{0.0f}; |   float accumulator_{0.0f}; | ||||||
| @@ -279,8 +264,6 @@ class HeartbeatFilter : public Filter, public Component { | |||||||
|  |  | ||||||
|   optional<float> new_value(float value) override; |   optional<float> new_value(float value) override; | ||||||
|  |  | ||||||
|   uint32_t expected_interval(uint32_t input) override; |  | ||||||
|  |  | ||||||
|   float get_setup_priority() const override; |   float get_setup_priority() const override; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
| @@ -306,8 +289,6 @@ class OrFilter : public Filter { | |||||||
|  |  | ||||||
|   void initialize(Sensor *parent, Filter *next) override; |   void initialize(Sensor *parent, Filter *next) override; | ||||||
|  |  | ||||||
|   uint32_t expected_interval(uint32_t input) override; |  | ||||||
|  |  | ||||||
|   optional<float> new_value(float value) override; |   optional<float> new_value(float value) override; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   | |||||||
| @@ -18,6 +18,51 @@ std::string state_class_to_string(StateClass state_class) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | Sensor::Sensor(const std::string &name) : Nameable(name), state(NAN), raw_state(NAN) {} | ||||||
|  | Sensor::Sensor() : Sensor("") {} | ||||||
|  |  | ||||||
|  | std::string Sensor::get_unit_of_measurement() { | ||||||
|  |   if (this->unit_of_measurement_.has_value()) | ||||||
|  |     return *this->unit_of_measurement_; | ||||||
|  |   return this->unit_of_measurement(); | ||||||
|  | } | ||||||
|  | void Sensor::set_unit_of_measurement(const std::string &unit_of_measurement) { | ||||||
|  |   this->unit_of_measurement_ = unit_of_measurement; | ||||||
|  | } | ||||||
|  | std::string Sensor::unit_of_measurement() { return ""; } | ||||||
|  |  | ||||||
|  | std::string Sensor::get_icon() { | ||||||
|  |   if (this->icon_.has_value()) | ||||||
|  |     return *this->icon_; | ||||||
|  |   return this->icon(); | ||||||
|  | } | ||||||
|  | void Sensor::set_icon(const std::string &icon) { this->icon_ = icon; } | ||||||
|  | std::string Sensor::icon() { return ""; } | ||||||
|  |  | ||||||
|  | int8_t Sensor::get_accuracy_decimals() { | ||||||
|  |   if (this->accuracy_decimals_.has_value()) | ||||||
|  |     return *this->accuracy_decimals_; | ||||||
|  |   return this->accuracy_decimals(); | ||||||
|  | } | ||||||
|  | void Sensor::set_accuracy_decimals(int8_t accuracy_decimals) { this->accuracy_decimals_ = accuracy_decimals; } | ||||||
|  | int8_t Sensor::accuracy_decimals() { return 0; } | ||||||
|  |  | ||||||
|  | std::string Sensor::get_device_class() { | ||||||
|  |   if (this->device_class_.has_value()) | ||||||
|  |     return *this->device_class_; | ||||||
|  |   return this->device_class(); | ||||||
|  | } | ||||||
|  | void Sensor::set_device_class(const std::string &device_class) { this->device_class_ = device_class; } | ||||||
|  | std::string Sensor::device_class() { return ""; } | ||||||
|  |  | ||||||
|  | void Sensor::set_state_class(StateClass state_class) { this->state_class_ = state_class; } | ||||||
|  | StateClass Sensor::get_state_class() { | ||||||
|  |   if (this->state_class_.has_value()) | ||||||
|  |     return *this->state_class_; | ||||||
|  |   return this->state_class(); | ||||||
|  | } | ||||||
|  | StateClass Sensor::state_class() { return StateClass::STATE_CLASS_NONE; } | ||||||
|  |  | ||||||
| void Sensor::publish_state(float state) { | void Sensor::publish_state(float state) { | ||||||
|   this->raw_state = state; |   this->raw_state = state; | ||||||
|   this->raw_callback_.call(state); |   this->raw_callback_.call(state); | ||||||
| @@ -30,54 +75,12 @@ void Sensor::publish_state(float state) { | |||||||
|     this->filter_list_->input(state); |     this->filter_list_->input(state); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| std::string Sensor::unit_of_measurement() { return ""; } |  | ||||||
| std::string Sensor::icon() { return ""; } |  | ||||||
| uint32_t Sensor::update_interval() { return 0; } |  | ||||||
| int8_t Sensor::accuracy_decimals() { return 0; } |  | ||||||
| Sensor::Sensor(const std::string &name) : Nameable(name), state(NAN), raw_state(NAN) {} |  | ||||||
| Sensor::Sensor() : Sensor("") {} |  | ||||||
|  |  | ||||||
| void Sensor::set_unit_of_measurement(const std::string &unit_of_measurement) { |  | ||||||
|   this->unit_of_measurement_ = unit_of_measurement; |  | ||||||
| } |  | ||||||
| void Sensor::set_icon(const std::string &icon) { this->icon_ = icon; } |  | ||||||
| void Sensor::set_accuracy_decimals(int8_t accuracy_decimals) { this->accuracy_decimals_ = accuracy_decimals; } |  | ||||||
| void Sensor::add_on_state_callback(std::function<void(float)> &&callback) { this->callback_.add(std::move(callback)); } | void Sensor::add_on_state_callback(std::function<void(float)> &&callback) { this->callback_.add(std::move(callback)); } | ||||||
| void Sensor::add_on_raw_state_callback(std::function<void(float)> &&callback) { | void Sensor::add_on_raw_state_callback(std::function<void(float)> &&callback) { | ||||||
|   this->raw_callback_.add(std::move(callback)); |   this->raw_callback_.add(std::move(callback)); | ||||||
| } | } | ||||||
| std::string Sensor::get_icon() { |  | ||||||
|   if (this->icon_.has_value()) |  | ||||||
|     return *this->icon_; |  | ||||||
|   return this->icon(); |  | ||||||
| } |  | ||||||
| void Sensor::set_device_class(const std::string &device_class) { this->device_class_ = device_class; } |  | ||||||
| std::string Sensor::get_device_class() { |  | ||||||
|   if (this->device_class_.has_value()) |  | ||||||
|     return *this->device_class_; |  | ||||||
|   return this->device_class(); |  | ||||||
| } |  | ||||||
| std::string Sensor::device_class() { return ""; } |  | ||||||
| void Sensor::set_state_class(StateClass state_class) { this->state_class = state_class; } |  | ||||||
| void Sensor::set_state_class(const std::string &state_class) { |  | ||||||
|   if (str_equals_case_insensitive(state_class, "measurement")) { |  | ||||||
|     this->state_class = STATE_CLASS_MEASUREMENT; |  | ||||||
|   } else if (str_equals_case_insensitive(state_class, "total_increasing")) { |  | ||||||
|     this->state_class = STATE_CLASS_TOTAL_INCREASING; |  | ||||||
|   } else { |  | ||||||
|     ESP_LOGW(TAG, "'%s' - Unrecognized state class %s", this->get_name().c_str(), state_class.c_str()); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| std::string Sensor::get_unit_of_measurement() { |  | ||||||
|   if (this->unit_of_measurement_.has_value()) |  | ||||||
|     return *this->unit_of_measurement_; |  | ||||||
|   return this->unit_of_measurement(); |  | ||||||
| } |  | ||||||
| int8_t Sensor::get_accuracy_decimals() { |  | ||||||
|   if (this->accuracy_decimals_.has_value()) |  | ||||||
|     return *this->accuracy_decimals_; |  | ||||||
|   return this->accuracy_decimals(); |  | ||||||
| } |  | ||||||
| void Sensor::add_filter(Filter *filter) { | void Sensor::add_filter(Filter *filter) { | ||||||
|   // inefficient, but only happens once on every sensor setup and nobody's going to have massive amounts of |   // inefficient, but only happens once on every sensor setup and nobody's going to have massive amounts of | ||||||
|   // filters |   // filters | ||||||
| @@ -119,24 +122,7 @@ void Sensor::internal_send_state_to_frontend(float state) { | |||||||
|   this->callback_.call(state); |   this->callback_.call(state); | ||||||
| } | } | ||||||
| bool Sensor::has_state() const { return this->has_state_; } | bool Sensor::has_state() const { return this->has_state_; } | ||||||
| uint32_t Sensor::calculate_expected_filter_update_interval() { |  | ||||||
|   uint32_t interval = this->update_interval(); |  | ||||||
|   if (interval == 4294967295UL) |  | ||||||
|     // update_interval: never |  | ||||||
|     return 0; |  | ||||||
|  |  | ||||||
|   if (this->filter_list_ == nullptr) { |  | ||||||
|     return interval; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return this->filter_list_->calculate_remaining_interval(interval); |  | ||||||
| } |  | ||||||
| uint32_t Sensor::hash_base() { return 2455723294UL; } | uint32_t Sensor::hash_base() { return 2455723294UL; } | ||||||
|  |  | ||||||
| PollingSensorComponent::PollingSensorComponent(const std::string &name, uint32_t update_interval) |  | ||||||
|     : PollingComponent(update_interval), Sensor(name) {} |  | ||||||
|  |  | ||||||
| uint32_t PollingSensorComponent::update_interval() { return this->get_update_interval(); } |  | ||||||
|  |  | ||||||
| }  // namespace sensor | }  // namespace sensor | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
| @@ -47,26 +47,42 @@ class Sensor : public Nameable { | |||||||
|   explicit Sensor(); |   explicit Sensor(); | ||||||
|   explicit Sensor(const std::string &name); |   explicit Sensor(const std::string &name); | ||||||
|  |  | ||||||
|   /** Manually set the unit of measurement of this sensor. By default the sensor's default defined by |   /// Get the unit of measurement, using the manual override if set. | ||||||
|    * unit_of_measurement() is used. |   std::string get_unit_of_measurement(); | ||||||
|    * |   /// Manually set the unit of measurement. | ||||||
|    * @param unit_of_measurement The unit of measurement, "" to disable. |  | ||||||
|    */ |  | ||||||
|   void set_unit_of_measurement(const std::string &unit_of_measurement); |   void set_unit_of_measurement(const std::string &unit_of_measurement); | ||||||
|  |  | ||||||
|   /** Manually set the icon of this sensor. By default the sensor's default defined by icon() is used. |   /// Get the icon. Uses the manual override if specified or the default value instead. | ||||||
|    * |   std::string get_icon(); | ||||||
|    * @param icon The icon, for example "mdi:flash". "" to disable. |   /// Manually set the icon, for example "mdi:flash". | ||||||
|    */ |  | ||||||
|   void set_icon(const std::string &icon); |   void set_icon(const std::string &icon); | ||||||
|  |  | ||||||
|   /** Manually set the accuracy in decimals for this sensor. By default, the sensor's default defined by |   /// Get the accuracy in decimals, using the manual override if set. | ||||||
|    * accuracy_decimals() is used. |   int8_t get_accuracy_decimals(); | ||||||
|    * |   /// Manually set the accuracy in decimals. | ||||||
|    * @param accuracy_decimals The accuracy decimal that should be used. |  | ||||||
|    */ |  | ||||||
|   void set_accuracy_decimals(int8_t accuracy_decimals); |   void set_accuracy_decimals(int8_t accuracy_decimals); | ||||||
|  |  | ||||||
|  |   /// Get the device class, using the manual override if set. | ||||||
|  |   std::string get_device_class(); | ||||||
|  |   /// Manually set the device class. | ||||||
|  |   void set_device_class(const std::string &device_class); | ||||||
|  |  | ||||||
|  |   /// Get the state class, using the manual override if set. | ||||||
|  |   StateClass get_state_class(); | ||||||
|  |   /// Manually set the state class. | ||||||
|  |   void set_state_class(StateClass state_class); | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Get whether force update mode is enabled. | ||||||
|  |    * | ||||||
|  |    * If the sensor is in force_update mode, the frontend is required to save all | ||||||
|  |    * state changes to the database when they are published, even if the state is the | ||||||
|  |    * same as before. | ||||||
|  |    */ | ||||||
|  |   bool get_force_update() const { return force_update_; } | ||||||
|  |   /// Set force update mode. | ||||||
|  |   void set_force_update(bool force_update) { force_update_ = force_update; } | ||||||
|  |  | ||||||
|   /// Add a filter to the filter chain. Will be appended to the back. |   /// Add a filter to the filter chain. Will be appended to the back. | ||||||
|   void add_filter(Filter *filter); |   void add_filter(Filter *filter); | ||||||
|  |  | ||||||
| @@ -93,15 +109,6 @@ class Sensor : public Nameable { | |||||||
|   /// Getter-syntax for .raw_state |   /// Getter-syntax for .raw_state | ||||||
|   float get_raw_state() const; |   float get_raw_state() const; | ||||||
|  |  | ||||||
|   /// Get the accuracy in decimals. Uses the manual override if specified or the default value instead. |  | ||||||
|   int8_t get_accuracy_decimals(); |  | ||||||
|  |  | ||||||
|   /// Get the unit of measurement. Uses the manual override if specified or the default value instead. |  | ||||||
|   std::string get_unit_of_measurement(); |  | ||||||
|  |  | ||||||
|   /// Get the Home Assistant Icon. Uses the manual override if specified or the default value instead. |  | ||||||
|   std::string get_icon(); |  | ||||||
|  |  | ||||||
|   /** Publish a new state to the front-end. |   /** Publish a new state to the front-end. | ||||||
|    * |    * | ||||||
|    * First, the new state will be assigned to the raw_value. Then it's passed through all filters |    * First, the new state will be assigned to the raw_value. Then it's passed through all filters | ||||||
| @@ -127,35 +134,15 @@ class Sensor : public Nameable { | |||||||
|    */ |    */ | ||||||
|   float state; |   float state; | ||||||
|  |  | ||||||
|   /// Manually set the Home Assistant device class (see sensor::device_class) |   /** This member variable stores the current raw state of the sensor, without any filters applied. | ||||||
|   void set_device_class(const std::string &device_class); |    * | ||||||
|  |    * Unlike .state,this will be updated immediately when publish_state is called. | ||||||
|   /// Get the device class for this sensor, using the manual override if specified. |  | ||||||
|   std::string get_device_class(); |  | ||||||
|  |  | ||||||
|   /** This member variable stores the current raw state of the sensor. Unlike .state, |  | ||||||
|    * this will be updated immediately when publish_state is called. |  | ||||||
|    */ |    */ | ||||||
|   float raw_state; |   float raw_state; | ||||||
|  |  | ||||||
|   /// Return whether this sensor has gotten a full state (that passed through all filters) yet. |   /// Return whether this sensor has gotten a full state (that passed through all filters) yet. | ||||||
|   bool has_state() const; |   bool has_state() const; | ||||||
|  |  | ||||||
|   // The state class of this sensor state |  | ||||||
|   StateClass state_class{STATE_CLASS_NONE}; |  | ||||||
|  |  | ||||||
|   /// Manually set the Home Assistant state class (see sensor::state_class) |  | ||||||
|   void set_state_class(StateClass state_class); |  | ||||||
|   void set_state_class(const std::string &state_class); |  | ||||||
|  |  | ||||||
|   /** Override this to set the Home Assistant device class for this sensor. |  | ||||||
|    * |  | ||||||
|    * Return "" to disable this feature. |  | ||||||
|    * |  | ||||||
|    * @return The device class of this sensor, for example "temperature". |  | ||||||
|    */ |  | ||||||
|   virtual std::string device_class(); |  | ||||||
|  |  | ||||||
|   /** A unique ID for this sensor, empty for no unique id. See unique ID requirements: |   /** A unique ID for this sensor, empty for no unique id. See unique ID requirements: | ||||||
|    * https://developers.home-assistant.io/docs/en/entity_registry_index.html#unique-id-requirements |    * https://developers.home-assistant.io/docs/en/entity_registry_index.html#unique-id-requirements | ||||||
|    * |    * | ||||||
| @@ -163,65 +150,38 @@ class Sensor : public Nameable { | |||||||
|    */ |    */ | ||||||
|   virtual std::string unique_id(); |   virtual std::string unique_id(); | ||||||
|  |  | ||||||
|   /// Return with which interval the sensor is polled. Return 0 for non-polling mode. |  | ||||||
|   virtual uint32_t update_interval(); |  | ||||||
|  |  | ||||||
|   /// Calculate the expected update interval for values that pass through all filters. |  | ||||||
|   uint32_t calculate_expected_filter_update_interval(); |  | ||||||
|  |  | ||||||
|   void internal_send_state_to_frontend(float state); |   void internal_send_state_to_frontend(float state); | ||||||
|  |  | ||||||
|   bool get_force_update() const { return force_update_; } |  | ||||||
|   /** Set this sensor's force_update mode. |  | ||||||
|    * |  | ||||||
|    * If the sensor is in force_update mode, the frontend is required to save all |  | ||||||
|    * state changes to the database when they are published, even if the state is the |  | ||||||
|    * same as before. |  | ||||||
|    */ |  | ||||||
|   void set_force_update(bool force_update) { force_update_ = force_update; } |  | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   /** Override this to set the Home Assistant unit of measurement for this sensor. |   /// Override this to set the default unit of measurement. | ||||||
|    * |  | ||||||
|    * Return "" to disable this feature. |  | ||||||
|    * |  | ||||||
|    * @return The icon of this sensor, for example "°C". |  | ||||||
|    */ |  | ||||||
|   virtual std::string unit_of_measurement();  // NOLINT |   virtual std::string unit_of_measurement();  // NOLINT | ||||||
|  |  | ||||||
|   /** Override this to set the Home Assistant icon for this sensor. |   /// Override this to set the default icon. | ||||||
|    * |  | ||||||
|    * Return "" to disable this feature. |  | ||||||
|    * |  | ||||||
|    * @return The icon of this sensor, for example "mdi:battery". |  | ||||||
|    */ |  | ||||||
|   virtual std::string icon();  // NOLINT |   virtual std::string icon();  // NOLINT | ||||||
|  |  | ||||||
|   /// Return the accuracy in decimals for this sensor. |   /// Override this to set the default accuracy in decimals. | ||||||
|   virtual int8_t accuracy_decimals();  // NOLINT |   virtual int8_t accuracy_decimals();  // NOLINT | ||||||
|  |  | ||||||
|   optional<std::string> device_class_{};  ///< Stores the override of the device class |   /// Override this to set the default device class. | ||||||
|  |   virtual std::string device_class();  // NOLINT | ||||||
|  |  | ||||||
|  |   /// Override this to set the default state class. | ||||||
|  |   virtual StateClass state_class();  // NOLINT | ||||||
|  |  | ||||||
|   uint32_t hash_base() override; |   uint32_t hash_base() override; | ||||||
|  |  | ||||||
|   CallbackManager<void(float)> raw_callback_;  ///< Storage for raw state callbacks. |   CallbackManager<void(float)> raw_callback_;  ///< Storage for raw state callbacks. | ||||||
|   CallbackManager<void(float)> callback_;      ///< Storage for filtered state callbacks. |   CallbackManager<void(float)> callback_;      ///< Storage for filtered state callbacks. | ||||||
|   /// Override the unit of measurement |  | ||||||
|   optional<std::string> unit_of_measurement_; |  | ||||||
|   /// Override the icon advertised to Home Assistant, otherwise sensor's icon will be used. |  | ||||||
|   optional<std::string> icon_; |  | ||||||
|   /// Override the accuracy in decimals, otherwise the sensor's values will be used. |  | ||||||
|   optional<int8_t> accuracy_decimals_; |  | ||||||
|   Filter *filter_list_{nullptr};  ///< Store all active filters. |  | ||||||
|   bool has_state_{false}; |   bool has_state_{false}; | ||||||
|   bool force_update_{false}; |   Filter *filter_list_{nullptr};  ///< Store all active filters. | ||||||
| }; |  | ||||||
|  |  | ||||||
| class PollingSensorComponent : public PollingComponent, public Sensor { |   optional<std::string> unit_of_measurement_;           ///< Unit of measurement override | ||||||
|  public: |   optional<std::string> icon_;                          ///< Icon override | ||||||
|   explicit PollingSensorComponent(const std::string &name, uint32_t update_interval); |   optional<int8_t> accuracy_decimals_;                  ///< Accuracy in decimals override | ||||||
|  |   optional<std::string> device_class_;                  ///< Device class override | ||||||
|   uint32_t update_interval() override; |   optional<StateClass> state_class_{STATE_CLASS_NONE};  ///< State class override | ||||||
|  |   bool force_update_{false};                            ///< Force update mode | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace sensor | }  // namespace sensor | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user