diff --git a/esphome/components/sen5x/sen5x.cpp b/esphome/components/sen5x/sen5x.cpp index 0efc96194386..d231a072c270 100644 --- a/esphome/components/sen5x/sen5x.cpp +++ b/esphome/components/sen5x/sen5x.cpp @@ -16,6 +16,7 @@ static const uint16_t SEN5X_CMD_GET_PRODUCT_NAME = 0xD014; static const uint16_t SEN5X_CMD_GET_SERIAL_NUMBER = 0xD033; static const uint16_t SEN5X_CMD_NOX_ALGORITHM_TUNING = 0x60E1; static const uint16_t SEN5X_CMD_READ_MEASUREMENT = 0x03C4; +static const uint16_t SEN5X_CMD_READ_PM_MEASUREMENT = 0x0413; static const uint16_t SEN5X_CMD_RHT_ACCELERATION_MODE = 0x60F7; static const uint16_t SEN5X_CMD_START_CLEANING_FAN = 0x5607; static const uint16_t SEN5X_CMD_START_MEASUREMENTS = 0x0021; @@ -28,6 +29,8 @@ static const uint16_t SEN5X_CMD_VOC_ALGORITHM_TUNING = 0x60D0; void SEN5XComponent::setup() { ESP_LOGCONFIG(TAG, "Setting up sen5x..."); + this->fsm_ = IDLE; + // the sensor needs 1000 ms to enter the idle state this->set_timeout(1000, [this]() { // Check if measurement is ready before reading the value @@ -126,14 +129,16 @@ void SEN5XComponent::setup() { this->nox_sensor_ = nullptr; // mark as not used } - if (!this->get_register(SEN5X_CMD_GET_FIRMWARE_VERSION, this->firmware_version_, 20)) { + uint16_t firmware_version; + if (!this->get_register(SEN5X_CMD_GET_FIRMWARE_VERSION, firmware_version, 20)) { ESP_LOGE(TAG, "Failed to read firmware version"); this->error_code_ = FIRMWARE_FAILED; this->mark_failed(); return; } - this->firmware_version_ >>= 8; - ESP_LOGD(TAG, "Firmware version %d", this->firmware_version_); + this->firmware_version_major_ = firmware_version >> 8; + this->firmware_version_minor_ = firmware_version & 0xFF; + ESP_LOGD(TAG, "Firmware version %u.%u", this->firmware_version_major_, this->firmware_version_minor_); if (this->voc_sensor_ && this->store_baseline_) { uint32_t combined_serial = @@ -215,9 +220,28 @@ void SEN5XComponent::setup() { delay(20); } + if ((this->pm_n_0_5_sensor_ || this->pm_n_1_0_sensor_ || this->pm_n_2_5_sensor_ || this->pm_n_4_0_sensor_ || + this->pm_n_10_0_sensor_ || this->pm_tps_sensor_)) { + if (this->firmware_version_major_ > 0 || this->firmware_version_minor_ > 7) { + this->get_pm_number_concentration_and_tps_ = true; + } else { + ESP_LOGE(TAG, "For number concentration and TPS, firmware >0.7 is required. You are using <%u.%u>", + this->firmware_version_major_, this->firmware_version_minor_); + this->pm_n_0_5_sensor_ = nullptr; + this->pm_n_1_0_sensor_ = nullptr; + this->pm_n_2_5_sensor_ = nullptr; + this->pm_n_4_0_sensor_ = nullptr; + this->pm_n_10_0_sensor_ = nullptr; + this->pm_tps_sensor_ = nullptr; + this->get_pm_number_concentration_and_tps_ = false; + } + } + // Finally start sensor measurements auto cmd = SEN5X_CMD_START_MEASUREMENTS_RHT_ONLY; - if (this->pm_1_0_sensor_ || this->pm_2_5_sensor_ || this->pm_4_0_sensor_ || this->pm_10_0_sensor_) { + if (this->pm_1_0_sensor_ || this->pm_2_5_sensor_ || this->pm_4_0_sensor_ || this->pm_10_0_sensor_ || + this->pm_n_0_5_sensor_ || this->pm_n_1_0_sensor_ || this->pm_n_2_5_sensor_ || this->pm_n_4_0_sensor_ || + this->pm_n_10_0_sensor_ || this->pm_tps_sensor_) { // if any of the gas sensors are active we need a full measurement cmd = SEN5X_CMD_START_MEASUREMENTS; } @@ -260,7 +284,7 @@ void SEN5XComponent::dump_config() { } } ESP_LOGCONFIG(TAG, " Productname: %s", this->product_name_.c_str()); - ESP_LOGCONFIG(TAG, " Firmware version: %d", this->firmware_version_); + ESP_LOGCONFIG(TAG, " Firmware version: %u.%u", this->firmware_version_major_, this->firmware_version_minor_); ESP_LOGCONFIG(TAG, " Serial number %02d.%02d.%02d", serial_number_[0], serial_number_[1], serial_number_[2]); if (this->auto_cleaning_interval_.has_value()) { ESP_LOGCONFIG(TAG, " Auto cleaning interval %" PRId32 " seconds", auto_cleaning_interval_.value()); @@ -283,6 +307,12 @@ void SEN5XComponent::dump_config() { LOG_SENSOR(" ", "PM 2.5", this->pm_2_5_sensor_); LOG_SENSOR(" ", "PM 4.0", this->pm_4_0_sensor_); LOG_SENSOR(" ", "PM 10.0", this->pm_10_0_sensor_); + LOG_SENSOR(" ", "PM_N 0.5", this->pm_n_0_5_sensor_); + LOG_SENSOR(" ", "PM_N 1.0", this->pm_n_1_0_sensor_); + LOG_SENSOR(" ", "PM_N 2.5", this->pm_n_2_5_sensor_); + LOG_SENSOR(" ", "PM_N 4.0", this->pm_n_4_0_sensor_); + LOG_SENSOR(" ", "PM_N 10.0", this->pm_n_10_0_sensor_); + LOG_SENSOR(" ", "PM_TPS", this->pm_tps_sensor_); LOG_SENSOR(" ", "Temperature", this->temperature_sensor_); LOG_SENSOR(" ", "Humidity", this->humidity_sensor_); LOG_SENSOR(" ", "VOC", this->voc_sensor_); // SEN54 and SEN55 only @@ -297,38 +327,116 @@ void SEN5XComponent::update() { // Store baselines after defined interval or if the difference between current and stored baseline becomes too // much if (this->store_baseline_ && this->seconds_since_last_store_ > SHORTEST_BASELINE_STORE_INTERVAL) { - if (this->write_command(SEN5X_CMD_VOC_ALGORITHM_STATE)) { - // run it a bit later to avoid adding a delay here - this->set_timeout(550, [this]() { - uint16_t states[4]; - if (this->read_data(states, 4)) { - uint32_t state0 = states[0] << 16 | states[1]; - uint32_t state1 = states[2] << 16 | states[3]; - if ((uint32_t) std::abs(static_cast(this->voc_baselines_storage_.state0 - state0)) > - MAXIMUM_STORAGE_DIFF || - (uint32_t) std::abs(static_cast(this->voc_baselines_storage_.state1 - state1)) > - MAXIMUM_STORAGE_DIFF) { - this->seconds_since_last_store_ = 0; - this->voc_baselines_storage_.state0 = state0; - this->voc_baselines_storage_.state1 = state1; - - if (this->pref_.save(&this->voc_baselines_storage_)) { - ESP_LOGI(TAG, "Stored VOC baseline state0: 0x%04" PRIX32 " ,state1: 0x%04" PRIX32, - this->voc_baselines_storage_.state0, voc_baselines_storage_.state1); - } else { - ESP_LOGW(TAG, "Could not store VOC baselines"); - } + this->write_voc_baseline_(); + } + + this->update_measured_values_(); + + if (this->get_pm_number_concentration_and_tps_) { + this->set_timeout(10, [this]() { this->trigger_update_measured_pm_(); }); + } +} + +void SEN5XComponent::trigger_update_measured_pm_() { + ESP_LOGD(TAG, "fsm: %d", this->fsm_); + if (this->fsm_ != VALUE_UPDATE_DONE) { + this->set_timeout(20, [this]() { this->trigger_update_measured_pm_(); }); + } else if (this->fsm_ == VALUE_UPDATE_DONE) { + this->update_measured_pm_(); + } +} + +float SEN5XComponent::get_valid_measurement_(uint16_t measurement, float scaling) { + if (measurement == 0xFFFF) { + return NAN; + } + return measurement / scaling; +} + +float SEN5XComponent::get_valid_measurement_signed_(uint16_t measurement, float scaling) { + if (measurement == 0x7FFF) { + return NAN; + } + return (int16_t) measurement / scaling; +} + +void SEN5XComponent::write_voc_baseline_() { + if (this->write_command(SEN5X_CMD_VOC_ALGORITHM_STATE)) { + // run it a bit later to avoid adding a delay here + this->set_timeout(550, [this]() { + uint16_t states[4]; + if (this->read_data(states, 4)) { + uint32_t state0 = states[0] << 16 | states[1]; + uint32_t state1 = states[2] << 16 | states[3]; + if ((uint32_t) std::abs(static_cast(this->voc_baselines_storage_.state0 - state0)) > + MAXIMUM_STORAGE_DIFF || + (uint32_t) std::abs(static_cast(this->voc_baselines_storage_.state1 - state1)) > + MAXIMUM_STORAGE_DIFF) { + this->seconds_since_last_store_ = 0; + this->voc_baselines_storage_.state0 = state0; + this->voc_baselines_storage_.state1 = state1; + + if (this->pref_.save(&this->voc_baselines_storage_)) { + ESP_LOGI(TAG, "Stored VOC baseline state0: 0x%04" PRIX32 " ,state1: 0x%04" PRIX32, + this->voc_baselines_storage_.state0, voc_baselines_storage_.state1); + } else { + ESP_LOGW(TAG, "Could not store VOC baselines"); } } - }); - } + } + }); + } +} + +void SEN5XComponent::update_measured_pm_() { + if (!this->write_command(SEN5X_CMD_READ_PM_MEASUREMENT)) { + this->status_set_warning(); + ESP_LOGD(TAG, "write error read measurement (%d)", this->last_error_); + return; } + this->set_timeout(20, [this]() { + uint16_t measurements[10]; + + if (!this->read_data(measurements, 10)) { + this->status_set_warning(); + ESP_LOGD(TAG, "read data error (%d)", this->last_error_); + return; + } + + float pm_n_0_5 = this->get_valid_measurement_(measurements[4], 10.0f); + float pm_n_1_0 = this->get_valid_measurement_(measurements[5], 10.0f); + float pm_n_2_5 = this->get_valid_measurement_(measurements[6], 10.0f); + float pm_n_4_0 = this->get_valid_measurement_(measurements[7], 10.0f); + float pm_n_10_0 = this->get_valid_measurement_(measurements[8], 10.0f); + float pm_tps = this->get_valid_measurement_(measurements[9], 1000.0f); + + if (this->pm_n_0_5_sensor_ != nullptr) + this->pm_n_0_5_sensor_->publish_state(pm_n_0_5); + if (this->pm_n_1_0_sensor_ != nullptr) + this->pm_n_1_0_sensor_->publish_state(pm_n_1_0); + if (this->pm_n_2_5_sensor_ != nullptr) + this->pm_n_2_5_sensor_->publish_state(pm_n_2_5); + if (this->pm_n_4_0_sensor_ != nullptr) + this->pm_n_4_0_sensor_->publish_state(pm_n_4_0); + if (this->pm_n_10_0_sensor_ != nullptr) + this->pm_n_10_0_sensor_->publish_state(pm_n_10_0); + if (this->pm_tps_sensor_ != nullptr) + this->pm_tps_sensor_->publish_state(pm_tps); + + this->status_clear_warning(); + this->fsm_ = IDLE; + }); +} + +void SEN5XComponent::update_measured_values_() { + this->fsm_ = VALUE_UPDATE_ONGOING; if (!this->write_command(SEN5X_CMD_READ_MEASUREMENT)) { this->status_set_warning(); ESP_LOGD(TAG, "write error read measurement (%d)", this->last_error_); return; } + this->set_timeout(20, [this]() { uint16_t measurements[8]; @@ -337,30 +445,16 @@ void SEN5XComponent::update() { ESP_LOGD(TAG, "read data error (%d)", this->last_error_); return; } - float pm_1_0 = measurements[0] / 10.0; - if (measurements[0] == 0xFFFF) - pm_1_0 = NAN; - float pm_2_5 = measurements[1] / 10.0; - if (measurements[1] == 0xFFFF) - pm_2_5 = NAN; - float pm_4_0 = measurements[2] / 10.0; - if (measurements[2] == 0xFFFF) - pm_4_0 = NAN; - float pm_10_0 = measurements[3] / 10.0; - if (measurements[3] == 0xFFFF) - pm_10_0 = NAN; - float humidity = measurements[4] / 100.0; - if (measurements[4] == 0xFFFF) - humidity = NAN; - float temperature = (int16_t) measurements[5] / 200.0; - if (measurements[5] == 0xFFFF) - temperature = NAN; - float voc = measurements[6] / 10.0; - if (measurements[6] == 0xFFFF) - voc = NAN; - float nox = measurements[7] / 10.0; - if (measurements[7] == 0xFFFF) - nox = NAN; + + float pm_1_0 = this->get_valid_measurement_(measurements[0], 10.0f); + float pm_2_5 = this->get_valid_measurement_(measurements[1], 10.0f); + float pm_4_0 = this->get_valid_measurement_(measurements[2], 10.0f); + float pm_10_0 = this->get_valid_measurement_(measurements[3], 10.0f); + + float humidity = this->get_valid_measurement_signed_(measurements[4], 100.0f); + float temperature = this->get_valid_measurement_signed_(measurements[5], 200.0f); + float voc = this->get_valid_measurement_signed_(measurements[6], 10.0f); + float nox = this->get_valid_measurement_signed_(measurements[7], 10.0f); if (this->pm_1_0_sensor_ != nullptr) this->pm_1_0_sensor_->publish_state(pm_1_0); @@ -378,7 +472,9 @@ void SEN5XComponent::update() { this->voc_sensor_->publish_state(voc); if (this->nox_sensor_ != nullptr) this->nox_sensor_->publish_state(nox); + this->status_clear_warning(); + this->fsm_ = VALUE_UPDATE_DONE; }); } diff --git a/esphome/components/sen5x/sen5x.h b/esphome/components/sen5x/sen5x.h index 6d90636a8985..8aaef48dc612 100644 --- a/esphome/components/sen5x/sen5x.h +++ b/esphome/components/sen5x/sen5x.h @@ -60,6 +60,13 @@ class SEN5XComponent : public PollingComponent, public sensirion_common::Sensiri void set_pm_4_0_sensor(sensor::Sensor *pm_4_0) { pm_4_0_sensor_ = pm_4_0; } void set_pm_10_0_sensor(sensor::Sensor *pm_10_0) { pm_10_0_sensor_ = pm_10_0; } + void set_pm_n_0_5_sensor(sensor::Sensor *pm_n_0_5) { pm_n_0_5_sensor_ = pm_n_0_5; } + void set_pm_n_1_0_sensor(sensor::Sensor *pm_n_1_0) { pm_n_1_0_sensor_ = pm_n_1_0; } + void set_pm_n_2_5_sensor(sensor::Sensor *pm_n_2_5) { pm_n_2_5_sensor_ = pm_n_2_5; } + void set_pm_n_4_0_sensor(sensor::Sensor *pm_n_4_0) { pm_n_4_0_sensor_ = pm_n_4_0; } + void set_pm_n_10_0_sensor(sensor::Sensor *pm_n_10_0) { pm_n_10_0_sensor_ = pm_n_10_0; } + void set_pm_tps_sensor(sensor::Sensor *pm_tps) { pm_tps_sensor_ = pm_tps; } + void set_voc_sensor(sensor::Sensor *voc_sensor) { voc_sensor_ = voc_sensor; } void set_nox_sensor(sensor::Sensor *nox_sensor) { nox_sensor_ = nox_sensor; } void set_humidity_sensor(sensor::Sensor *humidity_sensor) { humidity_sensor_ = humidity_sensor; } @@ -101,14 +108,29 @@ class SEN5XComponent : public PollingComponent, public sensirion_common::Sensiri bool start_fan_cleaning(); protected: + // Returns a valid measurement for an unsigned int, NAN otherwise + float get_valid_measurement_(uint16_t measurement, float scaling); + // Returns a valid measurement for a signed int, NAN otherwise + float get_valid_measurement_signed_(uint16_t measurement, float scaling); bool write_tuning_parameters_(uint16_t i2c_command, const GasTuning &tuning); bool write_temperature_compensation_(const TemperatureCompensation &compensation); + void write_voc_baseline_(); + void update_measured_values_(); + void update_measured_pm_(); + void trigger_update_measured_pm_(); ERRORCODE error_code_; bool initialized_{false}; sensor::Sensor *pm_1_0_sensor_{nullptr}; sensor::Sensor *pm_2_5_sensor_{nullptr}; sensor::Sensor *pm_4_0_sensor_{nullptr}; sensor::Sensor *pm_10_0_sensor_{nullptr}; + // Firmware >0.7 only + sensor::Sensor *pm_n_0_5_sensor_{nullptr}; + sensor::Sensor *pm_n_1_0_sensor_{nullptr}; + sensor::Sensor *pm_n_2_5_sensor_{nullptr}; + sensor::Sensor *pm_n_4_0_sensor_{nullptr}; + sensor::Sensor *pm_n_10_0_sensor_{nullptr}; + sensor::Sensor *pm_tps_sensor_{nullptr}; // SEN54 and SEN55 only sensor::Sensor *temperature_sensor_{nullptr}; sensor::Sensor *humidity_sensor_{nullptr}; @@ -118,7 +140,8 @@ class SEN5XComponent : public PollingComponent, public sensirion_common::Sensiri std::string product_name_; uint8_t serial_number_[4]; - uint16_t firmware_version_; + uint8_t firmware_version_major_; + uint8_t firmware_version_minor_; Sen5xBaselines voc_baselines_storage_; bool store_baseline_; uint32_t seconds_since_last_store_; @@ -128,6 +151,10 @@ class SEN5XComponent : public PollingComponent, public sensirion_common::Sensiri optional voc_tuning_params_; optional nox_tuning_params_; optional temperature_compensation_; + // Driver state variables + bool get_pm_number_concentration_and_tps_; + enum FsmStates { IDLE, VALUE_UPDATE_ONGOING, VALUE_UPDATE_DONE }; + FsmStates fsm_; }; } // namespace sen5x diff --git a/esphome/components/sen5x/sensor.py b/esphome/components/sen5x/sensor.py index 67bd627f7f4c..268270e00855 100644 --- a/esphome/components/sen5x/sensor.py +++ b/esphome/components/sen5x/sensor.py @@ -26,7 +26,9 @@ ICON_WATER_PERCENT, STATE_CLASS_MEASUREMENT, UNIT_CELSIUS, + UNIT_COUNTS_PER_CUBIC_CENTIMETER, UNIT_MICROGRAMS_PER_CUBIC_METER, + UNIT_MICROMETER, UNIT_PERCENT, ) @@ -40,6 +42,12 @@ ) RhtAccelerationMode = sen5x_ns.enum("RhtAccelerationMode") +CONF_PM_N_0_5 = "pm_n_0_5" +CONF_PM_N_1_0 = "pm_n_1_0" +CONF_PM_N_2_5 = "pm_n_2_5" +CONF_PM_N_4_0 = "pm_n_4_0" +CONF_PM_N_10_0 = "pm_n_10_0" +CONF_PM_TPS = "pm_tps" CONF_ACCELERATION_MODE = "acceleration_mode" CONF_ALGORITHM_TUNING = "algorithm_tuning" CONF_AUTO_CLEANING_INTERVAL = "auto_cleaning_interval" @@ -127,6 +135,42 @@ def float_previously_pct(value): device_class=DEVICE_CLASS_PM10, state_class=STATE_CLASS_MEASUREMENT, ), + cv.Optional(CONF_PM_N_0_5): sensor.sensor_schema( + unit_of_measurement=UNIT_COUNTS_PER_CUBIC_CENTIMETER, + icon=ICON_CHEMICAL_WEAPON, + accuracy_decimals=2, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_PM_N_1_0): sensor.sensor_schema( + unit_of_measurement=UNIT_COUNTS_PER_CUBIC_CENTIMETER, + icon=ICON_CHEMICAL_WEAPON, + accuracy_decimals=2, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_PM_N_2_5): sensor.sensor_schema( + unit_of_measurement=UNIT_COUNTS_PER_CUBIC_CENTIMETER, + icon=ICON_CHEMICAL_WEAPON, + accuracy_decimals=2, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_PM_N_4_0): sensor.sensor_schema( + unit_of_measurement=UNIT_COUNTS_PER_CUBIC_CENTIMETER, + icon=ICON_CHEMICAL_WEAPON, + accuracy_decimals=2, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_PM_N_10_0): sensor.sensor_schema( + unit_of_measurement=UNIT_COUNTS_PER_CUBIC_CENTIMETER, + icon=ICON_CHEMICAL_WEAPON, + accuracy_decimals=2, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_PM_TPS): sensor.sensor_schema( + unit_of_measurement=UNIT_MICROMETER, + icon=ICON_CHEMICAL_WEAPON, + accuracy_decimals=2, + state_class=STATE_CLASS_MEASUREMENT, + ), cv.Optional(CONF_AUTO_CLEANING_INTERVAL): cv.update_interval, cv.Optional(CONF_VOC): sensor.sensor_schema( icon=ICON_RADIATOR, @@ -177,6 +221,12 @@ def float_previously_pct(value): CONF_PM_2_5: "set_pm_2_5_sensor", CONF_PM_4_0: "set_pm_4_0_sensor", CONF_PM_10_0: "set_pm_10_0_sensor", + CONF_PM_N_0_5: "set_pm_n_0_5_sensor", + CONF_PM_N_1_0: "set_pm_n_1_0_sensor", + CONF_PM_N_2_5: "set_pm_n_2_5_sensor", + CONF_PM_N_4_0: "set_pm_n_4_0_sensor", + CONF_PM_N_10_0: "set_pm_n_10_0_sensor", + CONF_PM_TPS: "set_pm_tps_sensor", CONF_VOC: "set_voc_sensor", CONF_NOX: "set_nox_sensor", CONF_TEMPERATURE: "set_temperature_sensor", diff --git a/tests/components/sen5x/common.yaml b/tests/components/sen5x/common.yaml new file mode 100644 index 000000000000..ed284af938ea --- /dev/null +++ b/tests/components/sen5x/common.yaml @@ -0,0 +1,72 @@ +i2c: + - id: i2c_sen5x + scl: ${i2c_a_scl_pin} + sda: ${i2c_a_sda_pin} + +sensor: + - platform: sen5x + id: sen54 + temperature: + name: Temperature + accuracy_decimals: 1 + humidity: + name: Humidity + accuracy_decimals: 0 + pm_1_0: + name: PM <1µm Mass concentration + id: pm_1_0 + accuracy_decimals: 1 + pm_2_5: + name: PM <2.5µm Mass concentration + id: pm_2_5 + accuracy_decimals: 1 + pm_4_0: + name: PM <4µm Mass concentration + id: pm_4_0 + accuracy_decimals: 1 + pm_10_0: + name: PM <10µm Mass concentration + id: pm_10_0 + accuracy_decimals: 1 + pm_n_0_5: + name: PM <0.5µm Number concentration + id: pm_n_0_5 + accuracy_decimals: 1 + pm_n_1_0: + name: PM <1.0µm Number concentration + id: pm_n_1_0 + accuracy_decimals: 1 + pm_n_2_5: + name: PM <2.5µm Number concentration + id: pm_n_2_5 + accuracy_decimals: 1 + pm_n_4_0: + name: PM <4µm Number concentration + id: pm_n_4_0 + accuracy_decimals: 1 + pm_n_10_0: + name: PM <10µm Number concentration + accuracy_decimals: 1 + pm_tps: + name: Typical Particle size + id: pm_tps + accuracy_decimals: 1 + nox: + name: NOx + voc: + name: VOC + algorithm_tuning: + index_offset: 100 + learning_time_offset_hours: 12 + learning_time_gain_hours: 12 + gating_max_duration_minutes: 180 + std_initial: 50 + gain_factor: 230 + temperature_compensation: + offset: 0 + normalized_offset_slope: 0 + time_constant: 0 + auto_cleaning_interval: 604800s + acceleration_mode: low + store_baseline: true + address: 0x69 diff --git a/tests/components/sen5x/test.esp32-c3-idf.yaml b/tests/components/sen5x/test.esp32-c3-idf.yaml index 3352a59b1725..e2d3b1e1ada7 100644 --- a/tests/components/sen5x/test.esp32-c3-idf.yaml +++ b/tests/components/sen5x/test.esp32-c3-idf.yaml @@ -1,49 +1,5 @@ -i2c: - - id: i2c_sen5x - scl: 5 - sda: 4 +substitutions: + i2c_a_scl_pin: GPIO5 + i2c_a_sda_pin: GPIO4 -sensor: - - platform: sen5x - id: sen54 - temperature: - name: Temperature - accuracy_decimals: 1 - humidity: - name: Humidity - accuracy_decimals: 0 - pm_1_0: - name: PM <1µm Weight concentration - id: pm_1_0 - accuracy_decimals: 1 - pm_2_5: - name: PM <2.5µm Weight concentration - id: pm_2_5 - accuracy_decimals: 1 - pm_4_0: - name: PM <4µm Weight concentration - id: pm_4_0 - accuracy_decimals: 1 - pm_10_0: - name: PM <10µm Weight concentration - id: pm_10_0 - accuracy_decimals: 1 - nox: - name: NOx - voc: - name: VOC - algorithm_tuning: - index_offset: 100 - learning_time_offset_hours: 12 - learning_time_gain_hours: 12 - gating_max_duration_minutes: 180 - std_initial: 50 - gain_factor: 230 - temperature_compensation: - offset: 0 - normalized_offset_slope: 0 - time_constant: 0 - auto_cleaning_interval: 604800s - acceleration_mode: low - store_baseline: true - address: 0x69 +<<: !include common.yaml diff --git a/tests/components/sen5x/test.esp32-c3.yaml b/tests/components/sen5x/test.esp32-c3.yaml index 3352a59b1725..e2d3b1e1ada7 100644 --- a/tests/components/sen5x/test.esp32-c3.yaml +++ b/tests/components/sen5x/test.esp32-c3.yaml @@ -1,49 +1,5 @@ -i2c: - - id: i2c_sen5x - scl: 5 - sda: 4 +substitutions: + i2c_a_scl_pin: GPIO5 + i2c_a_sda_pin: GPIO4 -sensor: - - platform: sen5x - id: sen54 - temperature: - name: Temperature - accuracy_decimals: 1 - humidity: - name: Humidity - accuracy_decimals: 0 - pm_1_0: - name: PM <1µm Weight concentration - id: pm_1_0 - accuracy_decimals: 1 - pm_2_5: - name: PM <2.5µm Weight concentration - id: pm_2_5 - accuracy_decimals: 1 - pm_4_0: - name: PM <4µm Weight concentration - id: pm_4_0 - accuracy_decimals: 1 - pm_10_0: - name: PM <10µm Weight concentration - id: pm_10_0 - accuracy_decimals: 1 - nox: - name: NOx - voc: - name: VOC - algorithm_tuning: - index_offset: 100 - learning_time_offset_hours: 12 - learning_time_gain_hours: 12 - gating_max_duration_minutes: 180 - std_initial: 50 - gain_factor: 230 - temperature_compensation: - offset: 0 - normalized_offset_slope: 0 - time_constant: 0 - auto_cleaning_interval: 604800s - acceleration_mode: low - store_baseline: true - address: 0x69 +<<: !include common.yaml diff --git a/tests/components/sen5x/test.esp32-idf.yaml b/tests/components/sen5x/test.esp32-idf.yaml index b8f89c435f40..883155a43fee 100644 --- a/tests/components/sen5x/test.esp32-idf.yaml +++ b/tests/components/sen5x/test.esp32-idf.yaml @@ -1,49 +1,5 @@ -i2c: - - id: i2c_sen5x - scl: 16 - sda: 17 +substitutions: + i2c_a_scl_pin: GPIO16 + i2c_a_sda_pin: GPIO17 -sensor: - - platform: sen5x - id: sen54 - temperature: - name: Temperature - accuracy_decimals: 1 - humidity: - name: Humidity - accuracy_decimals: 0 - pm_1_0: - name: PM <1µm Weight concentration - id: pm_1_0 - accuracy_decimals: 1 - pm_2_5: - name: PM <2.5µm Weight concentration - id: pm_2_5 - accuracy_decimals: 1 - pm_4_0: - name: PM <4µm Weight concentration - id: pm_4_0 - accuracy_decimals: 1 - pm_10_0: - name: PM <10µm Weight concentration - id: pm_10_0 - accuracy_decimals: 1 - nox: - name: NOx - voc: - name: VOC - algorithm_tuning: - index_offset: 100 - learning_time_offset_hours: 12 - learning_time_gain_hours: 12 - gating_max_duration_minutes: 180 - std_initial: 50 - gain_factor: 230 - temperature_compensation: - offset: 0 - normalized_offset_slope: 0 - time_constant: 0 - auto_cleaning_interval: 604800s - acceleration_mode: low - store_baseline: true - address: 0x69 +<<: !include common.yaml diff --git a/tests/components/sen5x/test.esp32.yaml b/tests/components/sen5x/test.esp32.yaml index b8f89c435f40..883155a43fee 100644 --- a/tests/components/sen5x/test.esp32.yaml +++ b/tests/components/sen5x/test.esp32.yaml @@ -1,49 +1,5 @@ -i2c: - - id: i2c_sen5x - scl: 16 - sda: 17 +substitutions: + i2c_a_scl_pin: GPIO16 + i2c_a_sda_pin: GPIO17 -sensor: - - platform: sen5x - id: sen54 - temperature: - name: Temperature - accuracy_decimals: 1 - humidity: - name: Humidity - accuracy_decimals: 0 - pm_1_0: - name: PM <1µm Weight concentration - id: pm_1_0 - accuracy_decimals: 1 - pm_2_5: - name: PM <2.5µm Weight concentration - id: pm_2_5 - accuracy_decimals: 1 - pm_4_0: - name: PM <4µm Weight concentration - id: pm_4_0 - accuracy_decimals: 1 - pm_10_0: - name: PM <10µm Weight concentration - id: pm_10_0 - accuracy_decimals: 1 - nox: - name: NOx - voc: - name: VOC - algorithm_tuning: - index_offset: 100 - learning_time_offset_hours: 12 - learning_time_gain_hours: 12 - gating_max_duration_minutes: 180 - std_initial: 50 - gain_factor: 230 - temperature_compensation: - offset: 0 - normalized_offset_slope: 0 - time_constant: 0 - auto_cleaning_interval: 604800s - acceleration_mode: low - store_baseline: true - address: 0x69 +<<: !include common.yaml diff --git a/tests/components/sen5x/test.esp8266.yaml b/tests/components/sen5x/test.esp8266.yaml index 3352a59b1725..e2d3b1e1ada7 100644 --- a/tests/components/sen5x/test.esp8266.yaml +++ b/tests/components/sen5x/test.esp8266.yaml @@ -1,49 +1,5 @@ -i2c: - - id: i2c_sen5x - scl: 5 - sda: 4 +substitutions: + i2c_a_scl_pin: GPIO5 + i2c_a_sda_pin: GPIO4 -sensor: - - platform: sen5x - id: sen54 - temperature: - name: Temperature - accuracy_decimals: 1 - humidity: - name: Humidity - accuracy_decimals: 0 - pm_1_0: - name: PM <1µm Weight concentration - id: pm_1_0 - accuracy_decimals: 1 - pm_2_5: - name: PM <2.5µm Weight concentration - id: pm_2_5 - accuracy_decimals: 1 - pm_4_0: - name: PM <4µm Weight concentration - id: pm_4_0 - accuracy_decimals: 1 - pm_10_0: - name: PM <10µm Weight concentration - id: pm_10_0 - accuracy_decimals: 1 - nox: - name: NOx - voc: - name: VOC - algorithm_tuning: - index_offset: 100 - learning_time_offset_hours: 12 - learning_time_gain_hours: 12 - gating_max_duration_minutes: 180 - std_initial: 50 - gain_factor: 230 - temperature_compensation: - offset: 0 - normalized_offset_slope: 0 - time_constant: 0 - auto_cleaning_interval: 604800s - acceleration_mode: low - store_baseline: true - address: 0x69 +<<: !include common.yaml diff --git a/tests/components/sen5x/test.rp2040.yaml b/tests/components/sen5x/test.rp2040.yaml index 3352a59b1725..e2d3b1e1ada7 100644 --- a/tests/components/sen5x/test.rp2040.yaml +++ b/tests/components/sen5x/test.rp2040.yaml @@ -1,49 +1,5 @@ -i2c: - - id: i2c_sen5x - scl: 5 - sda: 4 +substitutions: + i2c_a_scl_pin: GPIO5 + i2c_a_sda_pin: GPIO4 -sensor: - - platform: sen5x - id: sen54 - temperature: - name: Temperature - accuracy_decimals: 1 - humidity: - name: Humidity - accuracy_decimals: 0 - pm_1_0: - name: PM <1µm Weight concentration - id: pm_1_0 - accuracy_decimals: 1 - pm_2_5: - name: PM <2.5µm Weight concentration - id: pm_2_5 - accuracy_decimals: 1 - pm_4_0: - name: PM <4µm Weight concentration - id: pm_4_0 - accuracy_decimals: 1 - pm_10_0: - name: PM <10µm Weight concentration - id: pm_10_0 - accuracy_decimals: 1 - nox: - name: NOx - voc: - name: VOC - algorithm_tuning: - index_offset: 100 - learning_time_offset_hours: 12 - learning_time_gain_hours: 12 - gating_max_duration_minutes: 180 - std_initial: 50 - gain_factor: 230 - temperature_compensation: - offset: 0 - normalized_offset_slope: 0 - time_constant: 0 - auto_cleaning_interval: 604800s - acceleration_mode: low - store_baseline: true - address: 0x69 +<<: !include common.yaml