ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
sfa30.cpp
Go to the documentation of this file.
1#include "sfa30.h"
2#include "esphome/core/log.h"
3
4namespace esphome::sfa30 {
5
6static const char *const TAG = "sfa30";
7
8static const uint16_t SFA30_CMD_GET_DEVICE_MARKING = 0xD060;
9static const uint16_t SFA30_CMD_START_CONTINUOUS_MEASUREMENTS = 0x0006;
10static const uint16_t SFA30_CMD_READ_MEASUREMENT = 0x0327;
11
13 // Serial Number identification
14 uint16_t raw_device_marking[16];
15 if (!this->get_register(SFA30_CMD_GET_DEVICE_MARKING, raw_device_marking, 16, 5)) {
16 ESP_LOGE(TAG, "Failed to read device marking");
17 this->error_code_ = DEVICE_MARKING_READ_FAILED;
18 this->mark_failed();
19 return;
20 }
21
22 for (size_t i = 0; i < 16; i++) {
23 this->device_marking_[i * 2] = static_cast<char>(raw_device_marking[i] >> 8);
24 this->device_marking_[i * 2 + 1] = static_cast<char>(raw_device_marking[i] & 0xFF);
25 }
26 ESP_LOGD(TAG, "Device Marking: '%s'", this->device_marking_);
27
28 if (!this->write_command(SFA30_CMD_START_CONTINUOUS_MEASUREMENTS)) {
29 ESP_LOGE(TAG, "Error starting measurements.");
30 this->error_code_ = MEASUREMENT_INIT_FAILED;
31 this->mark_failed();
32 return;
33 }
34}
35
37 ESP_LOGCONFIG(TAG, "sfa30:");
38 LOG_I2C_DEVICE(this);
39 if (this->is_failed()) {
40 switch (this->error_code_) {
41 case DEVICE_MARKING_READ_FAILED:
42 ESP_LOGW(TAG, "Unable to read device marking!");
43 break;
44 case MEASUREMENT_INIT_FAILED:
45 ESP_LOGW(TAG, "Measurement initialization failed!");
46 break;
47 default:
48 ESP_LOGW(TAG, "Unknown setup error!");
49 break;
50 }
51 }
52 LOG_UPDATE_INTERVAL(this);
53 ESP_LOGCONFIG(TAG, " Device Marking: '%s'", this->device_marking_);
54 LOG_SENSOR(" ", "Formaldehyde", this->formaldehyde_sensor_);
55 LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
56 LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
57}
58
60 if (!this->write_command(SFA30_CMD_READ_MEASUREMENT)) {
61 ESP_LOGW(TAG, "Error reading measurement!");
62 this->status_set_warning();
63 return;
64 }
65
66 this->set_timeout(5, [this]() {
67 uint16_t raw_data[3];
68 if (!this->read_data(raw_data, 3)) {
69 ESP_LOGW(TAG, "Error reading measurement data!");
70 this->status_set_warning();
71 return;
72 }
73
74 if (this->formaldehyde_sensor_ != nullptr) {
75 const float formaldehyde = static_cast<int16_t>(raw_data[0]) / 5.0f;
76 this->formaldehyde_sensor_->publish_state(formaldehyde);
77 }
78
79 if (this->humidity_sensor_ != nullptr) {
80 const float humidity = static_cast<int16_t>(raw_data[1]) / 100.0f;
81 this->humidity_sensor_->publish_state(humidity);
82 }
83
84 if (this->temperature_sensor_ != nullptr) {
85 const float temperature = static_cast<int16_t>(raw_data[2]) / 200.0f;
86 this->temperature_sensor_->publish_state(temperature);
87 }
88
90 });
91}
92
93} // namespace esphome::sfa30
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:272
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_timeout(const std voi set_timeout)(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition component.h:493
void status_clear_warning()
Definition component.h:289
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.
Definition sensor.cpp:68
sensor::Sensor * temperature_sensor_
Definition sfa30.h:28
void dump_config() override
Definition sfa30.cpp:36
sensor::Sensor * humidity_sensor_
Definition sfa30.h:27
sensor::Sensor * formaldehyde_sensor_
Definition sfa30.h:26
uint16_t temperature
Definition sun_gtil2.cpp:12