From e061b6dc5529428e17c64a909112d21d79553bdb Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Sun, 6 Jul 2025 08:37:50 -0500 Subject: [PATCH] [scd4x] Optimize logging + minor code clean-up (#9347) --- esphome/components/scd4x/scd4x.cpp | 108 ++++++++++++++++------------- esphome/components/scd4x/scd4x.h | 21 +++--- 2 files changed, 71 insertions(+), 58 deletions(-) diff --git a/esphome/components/scd4x/scd4x.cpp b/esphome/components/scd4x/scd4x.cpp index f617ffe276..4a700b70c2 100644 --- a/esphome/components/scd4x/scd4x.cpp +++ b/esphome/components/scd4x/scd4x.cpp @@ -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) diff --git a/esphome/components/scd4x/scd4x.h b/esphome/components/scd4x/scd4x.h index f2efb28ac1..237d226107 100644 --- a/esphome/components/scd4x/scd4x.h +++ b/esphome/components/scd4x/scd4x.h @@ -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};