10static const char *
const TAG = 
"sen5x";
 
   12static const uint16_t SEN5X_CMD_AUTO_CLEANING_INTERVAL = 0x8004;
 
   13static const uint16_t SEN5X_CMD_GET_DATA_READY_STATUS = 0x0202;
 
   14static const uint16_t SEN5X_CMD_GET_FIRMWARE_VERSION = 0xD100;
 
   15static const uint16_t SEN5X_CMD_GET_PRODUCT_NAME = 0xD014;
 
   16static const uint16_t SEN5X_CMD_GET_SERIAL_NUMBER = 0xD033;
 
   17static const uint16_t SEN5X_CMD_NOX_ALGORITHM_TUNING = 0x60E1;
 
   18static const uint16_t SEN5X_CMD_READ_MEASUREMENT = 0x03C4;
 
   19static const uint16_t SEN5X_CMD_RHT_ACCELERATION_MODE = 0x60F7;
 
   20static const uint16_t SEN5X_CMD_START_CLEANING_FAN = 0x5607;
 
   21static const uint16_t SEN5X_CMD_START_MEASUREMENTS = 0x0021;
 
   22static const uint16_t SEN5X_CMD_START_MEASUREMENTS_RHT_ONLY = 0x0037;
 
   23static const uint16_t SEN5X_CMD_STOP_MEASUREMENTS = 0x3f86;
 
   24static const uint16_t SEN5X_CMD_TEMPERATURE_COMPENSATION = 0x60B2;
 
   25static const uint16_t SEN5X_CMD_VOC_ALGORITHM_STATE = 0x6181;
 
   26static const uint16_t SEN5X_CMD_VOC_ALGORITHM_TUNING = 0x60D0;
 
   28static const int8_t SEN5X_INDEX_SCALE_FACTOR = 10;                            
 
   29static const int8_t SEN5X_MIN_INDEX_VALUE = 1 * SEN5X_INDEX_SCALE_FACTOR;     
 
   30static const int16_t SEN5X_MAX_INDEX_VALUE = 500 * SEN5X_INDEX_SCALE_FACTOR;  
 
   35      return LOG_STR(
"LOW");
 
   37      return LOG_STR(
"MEDIUM");
 
   39      return LOG_STR(
"HIGH");
 
   41      return LOG_STR(
"UNKNOWN");
 
   50      ESP_LOGE(TAG, 
"Failed to write data ready status command");
 
   56    uint16_t raw_read_status;
 
   58      ESP_LOGE(TAG, 
"Failed to read data ready status");
 
   63    uint32_t stop_measurement_delay = 0;
 
   65    if (raw_read_status) {
 
   66      ESP_LOGD(TAG, 
"Data is available; stopping periodic measurement");
 
   68        ESP_LOGE(TAG, 
"Failed to stop measurements");
 
   74      stop_measurement_delay = 200;
 
   76    this->
set_timeout(stop_measurement_delay, [
this]() {
 
   77      uint16_t raw_serial_number[3];
 
   78      if (!this->
get_register(SEN5X_CMD_GET_SERIAL_NUMBER, raw_serial_number, 3, 20)) {
 
   79        ESP_LOGE(TAG, 
"Failed to read serial number");
 
   84      this->
serial_number_[0] = 
static_cast<bool>(uint16_t(raw_serial_number[0]) & 0xFF);
 
   85      this->
serial_number_[1] = 
static_cast<uint16_t
>(raw_serial_number[0] & 0xFF);
 
   86      this->
serial_number_[2] = 
static_cast<uint16_t
>(raw_serial_number[1] >> 8);
 
   90      uint16_t raw_product_name[16];
 
   91      if (!this->
get_register(SEN5X_CMD_GET_PRODUCT_NAME, raw_product_name, 16, 20)) {
 
   92        ESP_LOGE(TAG, 
"Failed to read product name");
 
   98      const uint16_t *current_int = raw_product_name;
 
  103        current_char = *current_int >> 8;
 
  107          current_char = *current_int & 0xFF;
 
  113      } 
while (current_char && --max);
 
  126        ESP_LOGD(TAG, 
"Product name: %s", this->
product_name_.c_str());
 
  129        ESP_LOGE(TAG, 
"Relative humidity requires a SEN54 or SEN55");
 
  133        ESP_LOGE(TAG, 
"Temperature requires a SEN54 or SEN55");
 
  137        ESP_LOGE(TAG, 
"VOC requires a SEN54 or SEN55");
 
  141        ESP_LOGE(TAG, 
"NOx requires a SEN55");
 
  146        ESP_LOGE(TAG, 
"Failed to read firmware version");
 
  155        uint32_t combined_serial =
 
  163        if (this->
pref_.
load(&this->voc_baselines_storage_)) {
 
  164          ESP_LOGI(TAG, 
"Loaded VOC baseline state0: 0x%04" PRIX32 
", state1: 0x%04" PRIX32,
 
  172          ESP_LOGI(TAG, 
"Setting VOC baseline from save state0: 0x%04" PRIX32 
", state1: 0x%04" PRIX32,
 
  181          if (!this->
write_command(SEN5X_CMD_VOC_ALGORITHM_STATE, states, 4)) {
 
  182            ESP_LOGE(TAG, 
"Failed to set VOC baseline from saved state");
 
  203        result = this->
write_command(SEN5X_CMD_RHT_ACCELERATION_MODE);
 
  206        ESP_LOGE(TAG, 
"Failed to set rh/t acceleration mode");
 
  217          ESP_LOGE(TAG, 
"Failed to read RHT Acceleration mode");
 
  235      auto cmd = SEN5X_CMD_START_MEASUREMENTS_RHT_ONLY;
 
  238        cmd = SEN5X_CMD_START_MEASUREMENTS;
 
  242        ESP_LOGE(TAG, 
"Error starting continuous measurements");
 
 
  253  ESP_LOGCONFIG(TAG, 
"SEN5X:");
 
  254  LOG_I2C_DEVICE(
this);
 
  258        ESP_LOGW(TAG, ESP_LOG_MSG_COMM_FAIL);
 
  261        ESP_LOGW(TAG, 
"Measurement initialization failed");
 
  264        ESP_LOGW(TAG, 
"Unable to read serial ID");
 
  267        ESP_LOGW(TAG, 
"Unable to read product name");
 
  270        ESP_LOGW(TAG, 
"Unable to read firmware version");
 
  273        ESP_LOGW(TAG, 
"Unknown setup error");
 
  278                "  Product name: %s\n" 
  279                "  Firmware version: %d\n" 
  280                "  Serial number %02d.%02d.%02d",
 
  281                this->
product_name_.c_str(), this->firmware_version_, this->serial_number_[0], this->serial_number_[1],
 
  282                this->serial_number_[2]);
 
  287    ESP_LOGCONFIG(TAG, 
"  RH/T acceleration mode: %s",
 
  290  LOG_UPDATE_INTERVAL(
this);
 
 
  314          uint32_t state0 = states[0] << 16 | states[1];
 
  315          uint32_t state1 = states[2] << 16 | states[3];
 
  317                  MAXIMUM_STORAGE_DIFF ||
 
  318              (uint32_t) std::abs(
static_cast<int32_t
>(this->voc_baselines_storage_.state1 - state1)) >
 
  319                  MAXIMUM_STORAGE_DIFF) {
 
  324            if (this->
pref_.
save(&this->voc_baselines_storage_)) {
 
  325              ESP_LOGI(TAG, 
"Stored VOC baseline state0: 0x%04" PRIX32 
", state1: 0x%04" PRIX32,
 
  328              ESP_LOGW(TAG, 
"Could not store VOC baselines");
 
  338    ESP_LOGD(TAG, 
"Write error: read measurement (%d)", this->
last_error_);
 
  342    uint16_t measurements[8];
 
  346      ESP_LOGD(TAG, 
"Read data error (%d)", this->
last_error_);
 
  350    ESP_LOGVV(TAG, 
"pm_1_0 = 0x%.4x", measurements[0]);
 
  351    float pm_1_0 = measurements[0] == UINT16_MAX ? NAN : measurements[0] / 10.0f;
 
  353    ESP_LOGVV(TAG, 
"pm_2_5 = 0x%.4x", measurements[1]);
 
  354    float pm_2_5 = measurements[1] == UINT16_MAX ? NAN : measurements[1] / 10.0f;
 
  356    ESP_LOGVV(TAG, 
"pm_4_0 = 0x%.4x", measurements[2]);
 
  357    float pm_4_0 = measurements[2] == UINT16_MAX ? NAN : measurements[2] / 10.0f;
 
  359    ESP_LOGVV(TAG, 
"pm_10_0 = 0x%.4x", measurements[3]);
 
  360    float pm_10_0 = measurements[3] == UINT16_MAX ? NAN : measurements[3] / 10.0f;
 
  362    ESP_LOGVV(TAG, 
"humidity = 0x%.4x", measurements[4]);
 
  363    float humidity = measurements[4] == INT16_MAX ? NAN : 
static_cast<int16_t
>(measurements[4]) / 100.0f;
 
  365    ESP_LOGVV(TAG, 
"temperature = 0x%.4x", measurements[5]);
 
  366    float temperature = measurements[5] == INT16_MAX ? NAN : 
static_cast<int16_t
>(measurements[5]) / 200.0f;
 
  368    ESP_LOGVV(TAG, 
"voc = 0x%.4x", measurements[6]);
 
  369    int16_t voc_idx = 
static_cast<int16_t
>(measurements[6]);
 
  370    float voc = (voc_idx < SEN5X_MIN_INDEX_VALUE || voc_idx > SEN5X_MAX_INDEX_VALUE)
 
  372                    : 
static_cast<float>(voc_idx) / 10.0f;
 
  374    ESP_LOGVV(TAG, 
"nox = 0x%.4x", measurements[7]);
 
  375    int16_t nox_idx = 
static_cast<int16_t
>(measurements[7]);
 
  376    float nox = (nox_idx < SEN5X_MIN_INDEX_VALUE || nox_idx > SEN5X_MAX_INDEX_VALUE)
 
  378                    : 
static_cast<float>(nox_idx) / 10.0f;
 
 
  418    ESP_LOGE(TAG, 
"Set tuning parameters failed (command=%0xX, err=%d)", i2c_command, this->
last_error_);
 
 
  425  params[0] = compensation.
offset;
 
  428  if (!
write_command(SEN5X_CMD_TEMPERATURE_COMPENSATION, params, 3)) {
 
  429    ESP_LOGE(TAG, 
"Set temperature_compensation failed (%d)", this->
last_error_);
 
 
  438    ESP_LOGE(TAG, 
"Start fan cleaning failed (%d)", this->
last_error_);
 
  441    ESP_LOGD(TAG, 
"Fan auto clean started");
 
 
BedjetMode mode
BedJet operating mode.
 
std::string get_compilation_time() const
 
virtual void mark_failed()
Mark this component as failed.
 
void status_set_warning(const char *message=nullptr)
 
void status_clear_warning()
 
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
 
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
 
value_type const & value() const
 
optional< RhtAccelerationMode > acceleration_mode_
 
uint16_t firmware_version_
 
sensor::Sensor * pm_4_0_sensor_
 
void dump_config() override
 
ESPPreferenceObject pref_
 
bool write_tuning_parameters_(uint16_t i2c_command, const GasTuning &tuning)
 
sensor::Sensor * pm_2_5_sensor_
 
sensor::Sensor * temperature_sensor_
 
optional< uint32_t > auto_cleaning_interval_
 
sensor::Sensor * pm_1_0_sensor_
 
sensor::Sensor * voc_sensor_
 
optional< TemperatureCompensation > temperature_compensation_
 
sensor::Sensor * nox_sensor_
 
optional< GasTuning > voc_tuning_params_
 
sensor::Sensor * pm_10_0_sensor_
 
Sen5xBaselines voc_baselines_storage_
 
uint8_t serial_number_[4]
 
sensor::Sensor * humidity_sensor_
 
uint32_t seconds_since_last_store_
 
bool write_temperature_compensation_(const TemperatureCompensation &compensation)
 
bool start_fan_cleaning()
 
optional< GasTuning > nox_tuning_params_
 
std::string product_name_
 
i2c::ErrorCode last_error_
last error code from I2C operation
 
bool get_register(uint16_t command, uint16_t *data, uint8_t len, uint8_t delay=0)
get data words from I2C register.
 
bool write_command(T i2c_register)
Write a command to the I2C device.
 
bool read_data(uint16_t *data, uint8_t len)
Read data words from I2C device.
 
void publish_state(float state)
Publish a new state to the front-end.
 
@ MEASUREMENT_INIT_FAILED
 
@ SERIAL_NUMBER_IDENTIFICATION_FAILED
 
Providing packet encoding functions for exchanging data with a remote host.
 
constexpr uint32_t encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3)
Encode a 24-bit value given three bytes in most to least significant byte order.
 
ESPPreferences * global_preferences
 
uint32_t fnv1_hash(const char *str)
Calculate a FNV-1 hash of str.
 
void IRAM_ATTR HOT delay(uint32_t ms)
 
Application App
Global storage of Application pointer - only one Application can exist.
 
uint16_t learning_time_gain_hours
 
uint16_t gating_max_duration_minutes
 
uint16_t learning_time_offset_hours
 
int16_t normalized_offset_slope