mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
Queue sensor publishes so we don't block for too long (#3422)
This commit is contained in:
parent
2bff9937b7
commit
ebf13a0ba0
2 changed files with 33 additions and 19 deletions
|
@ -169,6 +169,14 @@ void BME680BSECComponent::loop() {
|
||||||
} else {
|
} else {
|
||||||
this->status_clear_warning();
|
this->status_clear_warning();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process a single action from the queue. These are primarily sensor state publishes
|
||||||
|
// that in totality take too long to send in a single call.
|
||||||
|
if (this->queue_.size()) {
|
||||||
|
auto action = std::move(this->queue_.front());
|
||||||
|
this->queue_.pop();
|
||||||
|
action();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BME680BSECComponent::run_() {
|
void BME680BSECComponent::run_() {
|
||||||
|
@ -306,37 +314,39 @@ void BME680BSECComponent::read_(int64_t trigger_time_ns, bsec_bme_settings_t bme
|
||||||
}
|
}
|
||||||
|
|
||||||
void BME680BSECComponent::publish_(const bsec_output_t *outputs, uint8_t num_outputs) {
|
void BME680BSECComponent::publish_(const bsec_output_t *outputs, uint8_t num_outputs) {
|
||||||
ESP_LOGV(TAG, "Publishing sensor states");
|
ESP_LOGV(TAG, "Queuing sensor state publish actions");
|
||||||
for (uint8_t i = 0; i < num_outputs; i++) {
|
for (uint8_t i = 0; i < num_outputs; i++) {
|
||||||
|
float signal = outputs[i].signal;
|
||||||
switch (outputs[i].sensor_id) {
|
switch (outputs[i].sensor_id) {
|
||||||
case BSEC_OUTPUT_IAQ:
|
case BSEC_OUTPUT_IAQ:
|
||||||
case BSEC_OUTPUT_STATIC_IAQ:
|
case BSEC_OUTPUT_STATIC_IAQ: {
|
||||||
uint8_t accuracy;
|
uint8_t accuracy = outputs[i].accuracy;
|
||||||
accuracy = outputs[i].accuracy;
|
this->queue_push_([this, signal]() { this->publish_sensor_(this->iaq_sensor_, signal); });
|
||||||
this->publish_sensor_state_(this->iaq_sensor_, outputs[i].signal);
|
this->queue_push_([this, accuracy]() {
|
||||||
this->publish_sensor_state_(this->iaq_accuracy_text_sensor_, IAQ_ACCURACY_STATES[accuracy]);
|
this->publish_sensor_(this->iaq_accuracy_text_sensor_, IAQ_ACCURACY_STATES[accuracy]);
|
||||||
this->publish_sensor_state_(this->iaq_accuracy_sensor_, accuracy, true);
|
});
|
||||||
|
this->queue_push_([this, accuracy]() { this->publish_sensor_(this->iaq_accuracy_sensor_, accuracy, true); });
|
||||||
|
|
||||||
// Queue up an opportunity to save state
|
// Queue up an opportunity to save state
|
||||||
this->defer("save_state", [this, accuracy]() { this->save_state_(accuracy); });
|
this->queue_push_([this, accuracy]() { this->save_state_(accuracy); });
|
||||||
break;
|
} break;
|
||||||
case BSEC_OUTPUT_CO2_EQUIVALENT:
|
case BSEC_OUTPUT_CO2_EQUIVALENT:
|
||||||
this->publish_sensor_state_(this->co2_equivalent_sensor_, outputs[i].signal);
|
this->queue_push_([this, signal]() { this->publish_sensor_(this->co2_equivalent_sensor_, signal); });
|
||||||
break;
|
break;
|
||||||
case BSEC_OUTPUT_BREATH_VOC_EQUIVALENT:
|
case BSEC_OUTPUT_BREATH_VOC_EQUIVALENT:
|
||||||
this->publish_sensor_state_(this->breath_voc_equivalent_sensor_, outputs[i].signal);
|
this->queue_push_([this, signal]() { this->publish_sensor_(this->breath_voc_equivalent_sensor_, signal); });
|
||||||
break;
|
break;
|
||||||
case BSEC_OUTPUT_RAW_PRESSURE:
|
case BSEC_OUTPUT_RAW_PRESSURE:
|
||||||
this->publish_sensor_state_(this->pressure_sensor_, outputs[i].signal / 100.0f);
|
this->queue_push_([this, signal]() { this->publish_sensor_(this->pressure_sensor_, signal / 100.0f); });
|
||||||
break;
|
break;
|
||||||
case BSEC_OUTPUT_RAW_GAS:
|
case BSEC_OUTPUT_RAW_GAS:
|
||||||
this->publish_sensor_state_(this->gas_resistance_sensor_, outputs[i].signal);
|
this->queue_push_([this, signal]() { this->publish_sensor_(this->gas_resistance_sensor_, signal); });
|
||||||
break;
|
break;
|
||||||
case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE:
|
case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE:
|
||||||
this->publish_sensor_state_(this->temperature_sensor_, outputs[i].signal);
|
this->queue_push_([this, signal]() { this->publish_sensor_(this->temperature_sensor_, signal); });
|
||||||
break;
|
break;
|
||||||
case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY:
|
case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY:
|
||||||
this->publish_sensor_state_(this->humidity_sensor_, outputs[i].signal);
|
this->queue_push_([this, signal]() { this->publish_sensor_(this->humidity_sensor_, signal); });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,14 +362,14 @@ int64_t BME680BSECComponent::get_time_ns_() {
|
||||||
return (time_ms + ((int64_t) this->millis_overflow_counter_ << 32)) * INT64_C(1000000);
|
return (time_ms + ((int64_t) this->millis_overflow_counter_ << 32)) * INT64_C(1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BME680BSECComponent::publish_sensor_state_(sensor::Sensor *sensor, float value, bool change_only) {
|
void BME680BSECComponent::publish_sensor_(sensor::Sensor *sensor, float value, bool change_only) {
|
||||||
if (!sensor || (change_only && sensor->has_state() && sensor->state == value)) {
|
if (!sensor || (change_only && sensor->has_state() && sensor->state == value)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sensor->publish_state(value);
|
sensor->publish_state(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BME680BSECComponent::publish_sensor_state_(text_sensor::TextSensor *sensor, const std::string &value) {
|
void BME680BSECComponent::publish_sensor_(text_sensor::TextSensor *sensor, const std::string &value) {
|
||||||
if (!sensor || (sensor->has_state() && sensor->state == value)) {
|
if (!sensor || (sensor->has_state() && sensor->state == value)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,12 +70,14 @@ class BME680BSECComponent : public Component, public i2c::I2CDevice {
|
||||||
void publish_(const bsec_output_t *outputs, uint8_t num_outputs);
|
void publish_(const bsec_output_t *outputs, uint8_t num_outputs);
|
||||||
int64_t get_time_ns_();
|
int64_t get_time_ns_();
|
||||||
|
|
||||||
void publish_sensor_state_(sensor::Sensor *sensor, float value, bool change_only = false);
|
void publish_sensor_(sensor::Sensor *sensor, float value, bool change_only = false);
|
||||||
void publish_sensor_state_(text_sensor::TextSensor *sensor, const std::string &value);
|
void publish_sensor_(text_sensor::TextSensor *sensor, const std::string &value);
|
||||||
|
|
||||||
void load_state_();
|
void load_state_();
|
||||||
void save_state_(uint8_t accuracy);
|
void save_state_(uint8_t accuracy);
|
||||||
|
|
||||||
|
void queue_push_(std::function<void()> &&f) { this->queue_.push(std::move(f)); }
|
||||||
|
|
||||||
struct bme680_dev bme680_;
|
struct bme680_dev bme680_;
|
||||||
bsec_library_return_t bsec_status_{BSEC_OK};
|
bsec_library_return_t bsec_status_{BSEC_OK};
|
||||||
int8_t bme680_status_{BME680_OK};
|
int8_t bme680_status_{BME680_OK};
|
||||||
|
@ -84,6 +86,8 @@ class BME680BSECComponent : public Component, public i2c::I2CDevice {
|
||||||
uint32_t millis_overflow_counter_{0};
|
uint32_t millis_overflow_counter_{0};
|
||||||
int64_t next_call_ns_{0};
|
int64_t next_call_ns_{0};
|
||||||
|
|
||||||
|
std::queue<std::function<void()>> queue_;
|
||||||
|
|
||||||
ESPPreferenceObject bsec_state_;
|
ESPPreferenceObject bsec_state_;
|
||||||
uint32_t state_save_interval_ms_{21600000}; // 6 hours - 4 times a day
|
uint32_t state_save_interval_ms_{21600000}; // 6 hours - 4 times a day
|
||||||
uint32_t last_state_save_ms_ = 0;
|
uint32_t last_state_save_ms_ = 0;
|
||||||
|
|
Loading…
Reference in a new issue