ESPHome  2024.3.2
sfa30.cpp
Go to the documentation of this file.
1 #include "sfa30.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace sfa30 {
6 
7 static const char *const TAG = "sfa30";
8 
9 static const uint16_t SFA30_CMD_GET_DEVICE_MARKING = 0xD060;
10 static const uint16_t SFA30_CMD_START_CONTINUOUS_MEASUREMENTS = 0x0006;
11 static const uint16_t SFA30_CMD_READ_MEASUREMENT = 0x0327;
12 
14  ESP_LOGCONFIG(TAG, "Setting up sfa30...");
15 
16  // Serial Number identification
17  uint16_t raw_device_marking[16];
18  if (!this->get_register(SFA30_CMD_GET_DEVICE_MARKING, raw_device_marking, 16, 5)) {
19  ESP_LOGE(TAG, "Failed to read device marking");
20  this->error_code_ = DEVICE_MARKING_READ_FAILED;
21  this->mark_failed();
22  return;
23  }
24 
25  for (size_t i = 0; i < 16; i++) {
26  this->device_marking_[i * 2] = static_cast<char>(raw_device_marking[i] >> 8);
27  this->device_marking_[i * 2 + 1] = static_cast<char>(raw_device_marking[i] & 0xFF);
28  }
29  ESP_LOGD(TAG, "Device Marking: '%s'", this->device_marking_);
30 
31  if (!this->write_command(SFA30_CMD_START_CONTINUOUS_MEASUREMENTS)) {
32  ESP_LOGE(TAG, "Error starting measurements.");
33  this->error_code_ = MEASUREMENT_INIT_FAILED;
34  this->mark_failed();
35  return;
36  }
37 
38  ESP_LOGD(TAG, "Sensor initialized");
39 }
40 
42  ESP_LOGCONFIG(TAG, "sfa30:");
43  LOG_I2C_DEVICE(this);
44  if (this->is_failed()) {
45  switch (this->error_code_) {
46  case DEVICE_MARKING_READ_FAILED:
47  ESP_LOGW(TAG, "Unable to read device marking!");
48  break;
49  case MEASUREMENT_INIT_FAILED:
50  ESP_LOGW(TAG, "Measurement initialization failed!");
51  break;
52  default:
53  ESP_LOGW(TAG, "Unknown setup error!");
54  break;
55  }
56  }
57  LOG_UPDATE_INTERVAL(this);
58  ESP_LOGCONFIG(TAG, " Device Marking: '%s'", this->device_marking_);
59  LOG_SENSOR(" ", "Formaldehyde", this->formaldehyde_sensor_);
60  LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
61  LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
62 }
63 
65  if (!this->write_command(SFA30_CMD_READ_MEASUREMENT)) {
66  ESP_LOGW(TAG, "Error reading measurement!");
67  this->status_set_warning();
68  return;
69  }
70 
71  this->set_timeout(5, [this]() {
72  uint16_t raw_data[3];
73  if (!this->read_data(raw_data, 3)) {
74  ESP_LOGW(TAG, "Error reading measurement data!");
75  this->status_set_warning();
76  return;
77  }
78 
79  if (this->formaldehyde_sensor_ != nullptr) {
80  const float formaldehyde = raw_data[0] / 5.0f;
81  this->formaldehyde_sensor_->publish_state(formaldehyde);
82  }
83 
84  if (this->humidity_sensor_ != nullptr) {
85  const float humidity = raw_data[1] / 100.0f;
86  this->humidity_sensor_->publish_state(humidity);
87  }
88 
89  if (this->temperature_sensor_ != nullptr) {
90  const float temperature = raw_data[2] / 200.0f;
91  this->temperature_sensor_->publish_state(temperature);
92  }
93 
94  this->status_clear_warning();
95  });
96 }
97 
98 } // namespace sfa30
99 } // namespace esphome
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:146
bool write_command(T i2c_register)
Write a command to the i2c device.
Definition: i2c_sensirion.h:82
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition: component.cpp:69
float temperature
Definition: qmp6988.h:71
bool read_data(uint16_t *data, uint8_t len)
Read data words from i2c device.
void dump_config() override
Definition: sfa30.cpp:41
sensor::Sensor * temperature_sensor_
Definition: sfa30.h:30
void status_clear_warning()
Definition: component.cpp:161
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
void setup() override
Definition: sfa30.cpp:13
sensor::Sensor * formaldehyde_sensor_
Definition: sfa30.h:28
bool get_register(uint16_t command, uint16_t *data, uint8_t len, uint8_t delay=0)
get data words from i2c register.
Definition: i2c_sensirion.h:43
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:113
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void update() override
Definition: sfa30.cpp:64
sensor::Sensor * humidity_sensor_
Definition: sfa30.h:29