mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[scd4x] Optimize logging + minor code clean-up (#9347)
This commit is contained in:
		| @@ -7,6 +7,8 @@ namespace scd4x { | ||||
|  | ||||
| static const char *const TAG = "scd4x"; | ||||
|  | ||||
| static const uint16_t SCD41_ID = 0x1408; | ||||
| static const uint16_t SCD40_ID = 0x440; | ||||
| static const uint16_t SCD4X_CMD_GET_SERIAL_NUMBER = 0x3682; | ||||
| static const uint16_t SCD4X_CMD_TEMPERATURE_OFFSET = 0x241d; | ||||
| static const uint16_t SCD4X_CMD_ALTITUDE_COMPENSATION = 0x2427; | ||||
| @@ -23,8 +25,6 @@ static const uint16_t SCD4X_CMD_STOP_MEASUREMENTS = 0x3f86; | ||||
| static const uint16_t SCD4X_CMD_FACTORY_RESET = 0x3632; | ||||
| static const uint16_t SCD4X_CMD_GET_FEATURESET = 0x202f; | ||||
| static const float SCD4X_TEMPERATURE_OFFSET_MULTIPLIER = (1 << 16) / 175.0f; | ||||
| static const uint16_t SCD41_ID = 0x1408; | ||||
| static const uint16_t SCD40_ID = 0x440; | ||||
|  | ||||
| void SCD4XComponent::setup() { | ||||
|   ESP_LOGCONFIG(TAG, "Running setup"); | ||||
| @@ -51,47 +51,66 @@ void SCD4XComponent::setup() { | ||||
|  | ||||
|       if (!this->write_command(SCD4X_CMD_TEMPERATURE_OFFSET, | ||||
|                                (uint16_t) (temperature_offset_ * SCD4X_TEMPERATURE_OFFSET_MULTIPLIER))) { | ||||
|         ESP_LOGE(TAG, "Error setting temperature offset."); | ||||
|         ESP_LOGE(TAG, "Error setting temperature offset"); | ||||
|         this->error_code_ = MEASUREMENT_INIT_FAILED; | ||||
|         this->mark_failed(); | ||||
|         return; | ||||
|       } | ||||
|  | ||||
|       // If pressure compensation available use it | ||||
|       // else use altitude | ||||
|       if (ambient_pressure_compensation_) { | ||||
|         if (!this->update_ambient_pressure_compensation_(ambient_pressure_)) { | ||||
|           ESP_LOGE(TAG, "Error setting ambient pressure compensation."); | ||||
|       // If pressure compensation available use it, else use altitude | ||||
|       if (this->ambient_pressure_compensation_) { | ||||
|         if (!this->update_ambient_pressure_compensation_(this->ambient_pressure_)) { | ||||
|           ESP_LOGE(TAG, "Error setting ambient pressure compensation"); | ||||
|           this->error_code_ = MEASUREMENT_INIT_FAILED; | ||||
|           this->mark_failed(); | ||||
|           return; | ||||
|         } | ||||
|       } else { | ||||
|         if (!this->write_command(SCD4X_CMD_ALTITUDE_COMPENSATION, altitude_compensation_)) { | ||||
|           ESP_LOGE(TAG, "Error setting altitude compensation."); | ||||
|         if (!this->write_command(SCD4X_CMD_ALTITUDE_COMPENSATION, this->altitude_compensation_)) { | ||||
|           ESP_LOGE(TAG, "Error setting altitude compensation"); | ||||
|           this->error_code_ = MEASUREMENT_INIT_FAILED; | ||||
|           this->mark_failed(); | ||||
|           return; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       if (!this->write_command(SCD4X_CMD_AUTOMATIC_SELF_CALIBRATION, enable_asc_ ? 1 : 0)) { | ||||
|         ESP_LOGE(TAG, "Error setting automatic self calibration."); | ||||
|       if (!this->write_command(SCD4X_CMD_AUTOMATIC_SELF_CALIBRATION, this->enable_asc_ ? 1 : 0)) { | ||||
|         ESP_LOGE(TAG, "Error setting automatic self calibration"); | ||||
|         this->error_code_ = MEASUREMENT_INIT_FAILED; | ||||
|         this->mark_failed(); | ||||
|         return; | ||||
|       } | ||||
|  | ||||
|       initialized_ = true; | ||||
|       this->initialized_ = true; | ||||
|       // Finally start sensor measurements | ||||
|       this->start_measurement_(); | ||||
|       ESP_LOGD(TAG, "Sensor initialized"); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
|  | ||||
| void SCD4XComponent::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "scd4x:"); | ||||
|   static const char *const MM_PERIODIC_STR = "Periodic (5s)"; | ||||
|   static const char *const MM_LOW_POWER_PERIODIC_STR = "Low power periodic (30s)"; | ||||
|   static const char *const MM_SINGLE_SHOT_STR = "Single shot"; | ||||
|   static const char *const MM_SINGLE_SHOT_RHT_ONLY_STR = "Single shot rht only"; | ||||
|   const char *measurement_mode_str = MM_PERIODIC_STR; | ||||
|  | ||||
|   switch (this->measurement_mode_) { | ||||
|     case PERIODIC: | ||||
|       // measurement_mode_str = MM_PERIODIC_STR; | ||||
|       break; | ||||
|     case LOW_POWER_PERIODIC: | ||||
|       measurement_mode_str = MM_LOW_POWER_PERIODIC_STR; | ||||
|       break; | ||||
|     case SINGLE_SHOT: | ||||
|       measurement_mode_str = MM_SINGLE_SHOT_STR; | ||||
|       break; | ||||
|     case SINGLE_SHOT_RHT_ONLY: | ||||
|       measurement_mode_str = MM_SINGLE_SHOT_RHT_ONLY_STR; | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   ESP_LOGCONFIG(TAG, "SCD4X:"); | ||||
|   LOG_I2C_DEVICE(this); | ||||
|   if (this->is_failed()) { | ||||
|     switch (this->error_code_) { | ||||
| @@ -102,16 +121,20 @@ void SCD4XComponent::dump_config() { | ||||
|         ESP_LOGW(TAG, "Measurement Initialization failed"); | ||||
|         break; | ||||
|       case SERIAL_NUMBER_IDENTIFICATION_FAILED: | ||||
|         ESP_LOGW(TAG, "Unable to read sensor firmware version"); | ||||
|         ESP_LOGW(TAG, "Unable to read firmware version"); | ||||
|         break; | ||||
|       default: | ||||
|         ESP_LOGW(TAG, "Unknown setup error"); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|   ESP_LOGCONFIG(TAG, "  Automatic self calibration: %s", ONOFF(this->enable_asc_)); | ||||
|   ESP_LOGCONFIG(TAG, | ||||
|                 "  Automatic self calibration: %s\n" | ||||
|                 "  Measurement mode: %s\n" | ||||
|                 "  Temperature offset: %.2f °C", | ||||
|                 ONOFF(this->enable_asc_), measurement_mode_str, this->temperature_offset_); | ||||
|   if (this->ambient_pressure_source_ != nullptr) { | ||||
|     ESP_LOGCONFIG(TAG, "  Dynamic ambient pressure compensation using sensor '%s'", | ||||
|     ESP_LOGCONFIG(TAG, "  Dynamic ambient pressure compensation using '%s'", | ||||
|                   this->ambient_pressure_source_->get_name().c_str()); | ||||
|   } else { | ||||
|     if (this->ambient_pressure_compensation_) { | ||||
| @@ -126,21 +149,6 @@ void SCD4XComponent::dump_config() { | ||||
|                     this->altitude_compensation_); | ||||
|     } | ||||
|   } | ||||
|   switch (this->measurement_mode_) { | ||||
|     case PERIODIC: | ||||
|       ESP_LOGCONFIG(TAG, "  Measurement mode: periodic (5s)"); | ||||
|       break; | ||||
|     case LOW_POWER_PERIODIC: | ||||
|       ESP_LOGCONFIG(TAG, "  Measurement mode: low power periodic (30s)"); | ||||
|       break; | ||||
|     case SINGLE_SHOT: | ||||
|       ESP_LOGCONFIG(TAG, "  Measurement mode: single shot"); | ||||
|       break; | ||||
|     case SINGLE_SHOT_RHT_ONLY: | ||||
|       ESP_LOGCONFIG(TAG, "  Measurement mode: single shot rht only"); | ||||
|       break; | ||||
|   } | ||||
|   ESP_LOGCONFIG(TAG, "  Temperature offset: %.2f °C", this->temperature_offset_); | ||||
|   LOG_UPDATE_INTERVAL(this); | ||||
|   LOG_SENSOR("  ", "CO2", this->co2_sensor_); | ||||
|   LOG_SENSOR("  ", "Temperature", this->temperature_sensor_); | ||||
| @@ -148,20 +156,20 @@ void SCD4XComponent::dump_config() { | ||||
| } | ||||
|  | ||||
| void SCD4XComponent::update() { | ||||
|   if (!initialized_) { | ||||
|   if (!this->initialized_) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (this->ambient_pressure_source_ != nullptr) { | ||||
|     float pressure = this->ambient_pressure_source_->state; | ||||
|     if (!std::isnan(pressure)) { | ||||
|       set_ambient_pressure_compensation(pressure); | ||||
|       this->set_ambient_pressure_compensation(pressure); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   uint32_t wait_time = 0; | ||||
|   if (this->measurement_mode_ == SINGLE_SHOT || this->measurement_mode_ == SINGLE_SHOT_RHT_ONLY) { | ||||
|     start_measurement_(); | ||||
|     this->start_measurement_(); | ||||
|     wait_time = | ||||
|         this->measurement_mode_ == SINGLE_SHOT ? 5000 : 50;  // Single shot measurement takes 5 secs rht mode 50 ms | ||||
|   } | ||||
| @@ -176,12 +184,12 @@ void SCD4XComponent::update() { | ||||
|  | ||||
|     if (!this->read_data(raw_read_status) || raw_read_status == 0x00) { | ||||
|       this->status_set_warning(); | ||||
|       ESP_LOGW(TAG, "Data not ready yet!"); | ||||
|       ESP_LOGW(TAG, "Data not ready"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     if (!this->write_command(SCD4X_CMD_READ_MEASUREMENT)) { | ||||
|       ESP_LOGW(TAG, "Error reading measurement!"); | ||||
|       ESP_LOGW(TAG, "Error reading measurement"); | ||||
|       this->status_set_warning(); | ||||
|       return;  // NO RETRY | ||||
|     } | ||||
| @@ -218,7 +226,7 @@ bool SCD4XComponent::perform_forced_calibration(uint16_t current_co2_concentrati | ||||
|   } | ||||
|   this->set_timeout(500, [this, current_co2_concentration]() { | ||||
|     if (this->write_command(SCD4X_CMD_PERFORM_FORCED_CALIBRATION, current_co2_concentration)) { | ||||
|       ESP_LOGD(TAG, "setting forced calibration Co2 level %d ppm", current_co2_concentration); | ||||
|       ESP_LOGD(TAG, "Setting forced calibration Co2 level %d ppm", current_co2_concentration); | ||||
|       // frc takes 400 ms | ||||
|       // because this method will be used very rarly | ||||
|       // the simple approach with delay is ok | ||||
| @@ -226,11 +234,11 @@ bool SCD4XComponent::perform_forced_calibration(uint16_t current_co2_concentrati | ||||
|       if (!this->start_measurement_()) { | ||||
|         return false; | ||||
|       } else { | ||||
|         ESP_LOGD(TAG, "forced calibration complete"); | ||||
|         ESP_LOGD(TAG, "Forced calibration complete"); | ||||
|       } | ||||
|       return true; | ||||
|     } else { | ||||
|       ESP_LOGE(TAG, "force calibration failed"); | ||||
|       ESP_LOGE(TAG, "Force calibration failed"); | ||||
|       this->error_code_ = FRC_FAILED; | ||||
|       this->status_set_warning(); | ||||
|       return false; | ||||
| @@ -261,25 +269,25 @@ bool SCD4XComponent::factory_reset() { | ||||
| void SCD4XComponent::set_ambient_pressure_compensation(float pressure_in_hpa) { | ||||
|   ambient_pressure_compensation_ = true; | ||||
|   uint16_t new_ambient_pressure = (uint16_t) pressure_in_hpa; | ||||
|   if (!initialized_) { | ||||
|     ambient_pressure_ = new_ambient_pressure; | ||||
|   if (!this->initialized_) { | ||||
|     this->ambient_pressure_ = new_ambient_pressure; | ||||
|     return; | ||||
|   } | ||||
|   // Only send pressure value if it has changed since last update | ||||
|   if (new_ambient_pressure != ambient_pressure_) { | ||||
|     update_ambient_pressure_compensation_(new_ambient_pressure); | ||||
|     ambient_pressure_ = new_ambient_pressure; | ||||
|   if (new_ambient_pressure != this->ambient_pressure_) { | ||||
|     this->update_ambient_pressure_compensation_(new_ambient_pressure); | ||||
|     this->ambient_pressure_ = new_ambient_pressure; | ||||
|   } else { | ||||
|     ESP_LOGD(TAG, "ambient pressure compensation skipped - no change required"); | ||||
|     ESP_LOGD(TAG, "Ambient pressure compensation skipped; no change required"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool SCD4XComponent::update_ambient_pressure_compensation_(uint16_t pressure_in_hpa) { | ||||
|   if (this->write_command(SCD4X_CMD_AMBIENT_PRESSURE_COMPENSATION, pressure_in_hpa)) { | ||||
|     ESP_LOGD(TAG, "setting ambient pressure compensation to %d hPa", pressure_in_hpa); | ||||
|     ESP_LOGD(TAG, "Setting ambient pressure compensation to %d hPa", pressure_in_hpa); | ||||
|     return true; | ||||
|   } else { | ||||
|     ESP_LOGE(TAG, "Error setting ambient pressure compensation."); | ||||
|     ESP_LOGE(TAG, "Error setting ambient pressure compensation"); | ||||
|     return false; | ||||
|   } | ||||
| } | ||||
| @@ -304,7 +312,7 @@ bool SCD4XComponent::start_measurement_() { | ||||
|   static uint8_t remaining_retries = 3; | ||||
|   while (remaining_retries) { | ||||
|     if (!this->write_command(measurement_command)) { | ||||
|       ESP_LOGE(TAG, "Error starting measurements."); | ||||
|       ESP_LOGE(TAG, "Error starting measurements"); | ||||
|       this->error_code_ = MEASUREMENT_INIT_FAILED; | ||||
|       this->status_set_warning(); | ||||
|       if (--remaining_retries == 0) | ||||
|   | ||||
| @@ -8,14 +8,20 @@ | ||||
| namespace esphome { | ||||
| namespace scd4x { | ||||
|  | ||||
| enum ERRORCODE { | ||||
| enum ErrorCode : uint8_t { | ||||
|   COMMUNICATION_FAILED, | ||||
|   SERIAL_NUMBER_IDENTIFICATION_FAILED, | ||||
|   MEASUREMENT_INIT_FAILED, | ||||
|   FRC_FAILED, | ||||
|   UNKNOWN | ||||
|   UNKNOWN, | ||||
| }; | ||||
|  | ||||
| enum MeasurementMode : uint8_t { | ||||
|   PERIODIC, | ||||
|   LOW_POWER_PERIODIC, | ||||
|   SINGLE_SHOT, | ||||
|   SINGLE_SHOT_RHT_ONLY, | ||||
| }; | ||||
| enum MeasurementMode { PERIODIC, LOW_POWER_PERIODIC, SINGLE_SHOT, SINGLE_SHOT_RHT_ONLY }; | ||||
|  | ||||
| class SCD4XComponent : public PollingComponent, public sensirion_common::SensirionI2CDevice { | ||||
|  public: | ||||
| @@ -39,15 +45,14 @@ class SCD4XComponent : public PollingComponent, public sensirion_common::Sensiri | ||||
|  protected: | ||||
|   bool update_ambient_pressure_compensation_(uint16_t pressure_in_hpa); | ||||
|   bool start_measurement_(); | ||||
|   ERRORCODE error_code_; | ||||
|  | ||||
|   bool initialized_{false}; | ||||
|  | ||||
|   float temperature_offset_; | ||||
|   uint16_t altitude_compensation_; | ||||
|   bool ambient_pressure_compensation_; | ||||
|   uint16_t ambient_pressure_; | ||||
|   bool initialized_{false}; | ||||
|   bool ambient_pressure_compensation_; | ||||
|   bool enable_asc_; | ||||
|   float temperature_offset_; | ||||
|   ErrorCode error_code_; | ||||
|   MeasurementMode measurement_mode_{PERIODIC}; | ||||
|   sensor::Sensor *co2_sensor_{nullptr}; | ||||
|   sensor::Sensor *temperature_sensor_{nullptr}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user