diff --git a/esphome/components/sgp30/sensor.py b/esphome/components/sgp30/sensor.py index 6329b122fd..a52811eb34 100644 --- a/esphome/components/sgp30/sensor.py +++ b/esphome/components/sgp30/sensor.py @@ -12,6 +12,8 @@ SGP30Component = sgp30_ns.class_('SGP30Component', cg.PollingComponent, i2c.I2CD CONF_ECO2 = 'eco2' CONF_TVOC = 'tvoc' CONF_BASELINE = 'baseline' +CONF_ECO2_BASELINE = 'eco2_baseline' +CONF_TVOC_BASELINE = 'tvoc_baseline' CONF_UPTIME = 'uptime' CONF_COMPENSATION = 'compensation' CONF_HUMIDITY_SOURCE = 'humidity_source' @@ -22,7 +24,10 @@ CONFIG_SCHEMA = cv.Schema({ cv.Required(CONF_ECO2): sensor.sensor_schema(UNIT_PARTS_PER_MILLION, ICON_PERIODIC_TABLE_CO2, 0), cv.Required(CONF_TVOC): sensor.sensor_schema(UNIT_PARTS_PER_BILLION, ICON_RADIATOR, 0), - cv.Optional(CONF_BASELINE): cv.hex_uint16_t, + cv.Optional(CONF_BASELINE): cv.Schema({ + cv.Required(CONF_ECO2_BASELINE): cv.hex_uint16_t, + cv.Required(CONF_TVOC_BASELINE): cv.hex_uint16_t, + }), cv.Optional(CONF_COMPENSATION): cv.Schema({ cv.Required(CONF_HUMIDITY_SOURCE): cv.use_id(sensor.Sensor), cv.Required(CONF_TEMPERATURE_SOURCE): cv.use_id(sensor.Sensor) @@ -44,7 +49,9 @@ def to_code(config): cg.add(var.set_tvoc_sensor(sens)) if CONF_BASELINE in config: - cg.add(var.set_baseline(config[CONF_BASELINE])) + baseline_config = config[CONF_BASELINE] + cg.add(var.set_eco2_baseline(baseline_config[CONF_ECO2_BASELINE])) + cg.add(var.set_tvoc_baseline(baseline_config[CONF_TVOC_BASELINE])) if CONF_COMPENSATION in config: compensation_config = config[CONF_COMPENSATION] diff --git a/esphome/components/sgp30/sgp30.cpp b/esphome/components/sgp30/sgp30.cpp index 9a73295447..8c148b8e83 100644 --- a/esphome/components/sgp30/sgp30.cpp +++ b/esphome/components/sgp30/sgp30.cpp @@ -74,9 +74,9 @@ void SGP30Component::setup() { } // Sensor baseline reliability timer - if (this->baseline_ > 0) { + if (this->eco2_baseline_ > 0 && this->tvoc_baseline_ > 0) { this->required_warm_up_time_ = IAQ_BASELINE_WARM_UP_SECONDS_WITH_BASELINE_PROVIDED; - this->write_iaq_baseline_(this->baseline_); + this->write_iaq_baseline_(this->eco2_baseline_, this->tvoc_baseline_); } else { this->required_warm_up_time_ = IAQ_BASELINE_WARM_UP_SECONDS_WITHOUT_BASELINE; } @@ -106,10 +106,10 @@ void SGP30Component::read_iaq_baseline_() { return; } - uint8_t eco2baseline = (raw_data[0]); - uint8_t tvocbaseline = (raw_data[1]); + uint16_t eco2baseline = (raw_data[0]); + uint16_t tvocbaseline = (raw_data[1]); - ESP_LOGI(TAG, "Current eCO2 & TVOC baseline: 0x%04X", uint16_t((eco2baseline << 8) | (tvocbaseline & 0xFF))); + ESP_LOGI(TAG, "Current eCO2 baseline: 0x%04X, TVOC baseline: 0x%04X", eco2baseline, tvocbaseline); this->status_clear_warning(); }); } else { @@ -159,18 +159,19 @@ void SGP30Component::send_env_data_() { } } -void SGP30Component::write_iaq_baseline_(uint16_t baseline) { - uint8_t e_c_o2_baseline = baseline >> 8; - uint8_t tvoc_baseline = baseline & 0xFF; - uint8_t data[4]; +void SGP30Component::write_iaq_baseline_(uint16_t eco2_baseline, uint16_t tvoc_baseline) { + uint8_t data[7]; data[0] = SGP30_CMD_SET_IAQ_BASELINE & 0xFF; - data[1] = e_c_o2_baseline; - data[2] = tvoc_baseline; - data[3] = sht_crc_(e_c_o2_baseline, tvoc_baseline); - if (!this->write_bytes(SGP30_CMD_SET_IAQ_BASELINE >> 8, data, 4)) { - ESP_LOGE(TAG, "Error applying baseline: 0x%04X", baseline); + data[1] = eco2_baseline >> 8; + data[2] = eco2_baseline & 0xFF; + data[3] = sht_crc_(data[1], data[2]); + data[4] = tvoc_baseline >> 8; + data[5] = tvoc_baseline & 0xFF; + data[6] = sht_crc_(data[4], data[5]); + if (!this->write_bytes(SGP30_CMD_SET_IAQ_BASELINE >> 8, data, 7)) { + ESP_LOGE(TAG, "Error applying eCO2 baseline: 0x%04X, TVOC baseline: 0x%04X", eco2_baseline, tvoc_baseline); } else - ESP_LOGI(TAG, "Initial baseline 0x%04X applied successfully!", baseline); + ESP_LOGI(TAG, "Initial eCO2 and TVOC baselines applied successfully!"); } void SGP30Component::dump_config() { @@ -196,8 +197,13 @@ void SGP30Component::dump_config() { } } else { ESP_LOGCONFIG(TAG, " Serial number: %llu", this->serial_number_); - ESP_LOGCONFIG(TAG, " Baseline: 0x%04X%s", this->baseline_, - ((this->baseline_ != 0x0000) ? " (enabled)" : " (disabled)")); + if (this->eco2_baseline_ != 0x0000 && this->tvoc_baseline_ != 0x0000) { + ESP_LOGCONFIG(TAG, " Baseline:"); + ESP_LOGCONFIG(TAG, " eCO2 Baseline: 0x%04X", this->eco2_baseline_); + ESP_LOGCONFIG(TAG, " TVOC Baseline: 0x%04X", this->tvoc_baseline_); + } else { + ESP_LOGCONFIG(TAG, " Baseline: No baseline configured"); + } ESP_LOGCONFIG(TAG, " Warm up time: %lds", this->required_warm_up_time_); } LOG_UPDATE_INTERVAL(this); diff --git a/esphome/components/sgp30/sgp30.h b/esphome/components/sgp30/sgp30.h index 2362d1bca6..27572e9c46 100644 --- a/esphome/components/sgp30/sgp30.h +++ b/esphome/components/sgp30/sgp30.h @@ -13,7 +13,8 @@ class SGP30Component : public PollingComponent, public i2c::I2CDevice { public: void set_eco2_sensor(sensor::Sensor *eco2) { eco2_sensor_ = eco2; } void set_tvoc_sensor(sensor::Sensor *tvoc) { tvoc_sensor_ = tvoc; } - void set_baseline(uint16_t baseline) { baseline_ = baseline; } + void set_eco2_baseline(uint16_t eco2_baseline) { eco2_baseline_ = eco2_baseline; } + void set_tvoc_baseline(uint16_t tvoc_baseline) { tvoc_baseline_ = tvoc_baseline; } void set_humidity_sensor(sensor::Sensor *humidity) { humidity_sensor_ = humidity; } void set_temperature_sensor(sensor::Sensor *temperature) { temperature_sensor_ = temperature; } @@ -28,7 +29,7 @@ class SGP30Component : public PollingComponent, public i2c::I2CDevice { void send_env_data_(); void read_iaq_baseline_(); bool is_sensor_baseline_reliable_(); - void write_iaq_baseline_(uint16_t baseline); + void write_iaq_baseline_(uint16_t eco2_baseline, uint16_t tvoc_baseline); uint8_t sht_crc_(uint8_t data1, uint8_t data2); uint64_t serial_number_; uint16_t featureset_; @@ -44,7 +45,8 @@ class SGP30Component : public PollingComponent, public i2c::I2CDevice { sensor::Sensor *eco2_sensor_{nullptr}; sensor::Sensor *tvoc_sensor_{nullptr}; - uint16_t baseline_{0x0000}; + uint16_t eco2_baseline_{0x0000}; + uint16_t tvoc_baseline_{0x0000}; /// Input sensor for humidity and temperature compensation. sensor::Sensor *humidity_sensor_{nullptr}; sensor::Sensor *temperature_sensor_{nullptr};