pulse_counter: When using Time, don't update until time sync

Avoids nonphysical spikes across reboots, sleeps or time syncs
This commit is contained in:
brisk 2024-04-18 00:02:38 +09:30
parent b230491fd2
commit f2046573fb
2 changed files with 17 additions and 6 deletions

View file

@ -251,6 +251,9 @@ void PulseCounterSensor::setup() {
this->mark_failed(); this->mark_failed();
return; return;
} }
#ifdef CONF_USE_TIME
this->time_id_->add_on_time_sync_callback([this]() { this->time_is_synchronized = true; });
#endif
} }
void PulseCounterSensor::set_total_pulses(uint32_t pulses) { void PulseCounterSensor::set_total_pulses(uint32_t pulses) {
@ -268,19 +271,26 @@ void PulseCounterSensor::dump_config() {
} }
void PulseCounterSensor::update() { void PulseCounterSensor::update() {
#ifdef CONF_USE_TIME
// Can't clear the pulse count until we can report the rate, so there's
// nothing to do until the time is synchronized
if (!time_is_synchronized) {
return;
}
#endif
pulse_counter_t raw = this->storage_.read_raw_value(); pulse_counter_t raw = this->storage_.read_raw_value();
timestamp_t now; timestamp_t now;
timestamp_t interval;
#ifdef CONF_USE_TIME #ifdef CONF_USE_TIME
if (this->time_id_ != nullptr) { now = this->time_id_->timestamp_now();
now = this->time_id_->timestamp_now() * 1000; // Convert to ms to match units when not using a Time component.
} else { interval = (now - this->last_time_) * 1000;
now = millis();
}
#else #else
now = millis(); now = millis();
interval = now - this->last_time_;
#endif #endif
if (this->last_time_ != 0) { if (this->last_time_ != 0) {
timestamp_t interval = now - this->last_time_;
float value = (60000.0f * raw) / float(interval); // per minute float value = (60000.0f * raw) / float(interval); // per minute
ESP_LOGD(TAG, "'%s': Retrieved counter: %0.2f pulses/min", this->get_name().c_str(), value); ESP_LOGD(TAG, "'%s': Retrieved counter: %0.2f pulses/min", this->get_name().c_str(), value);
this->publish_state(value); this->publish_state(value);

View file

@ -102,6 +102,7 @@ class PulseCounterSensor : public sensor::Sensor, public PollingComponent {
sensor::Sensor *total_sensor_{nullptr}; sensor::Sensor *total_sensor_{nullptr};
#ifdef USE_TIME #ifdef USE_TIME
time::RealTimeClock *time_id_{nullptr}; time::RealTimeClock *time_id_{nullptr};
bool time_is_synchronized{false};
#endif #endif
}; };