ESPHome 2025.5.2
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
sfa30.cpp
Go to the documentation of this file.
1#include "sfa30.h"
2#include "esphome/core/log.h"
3
4namespace esphome {
5namespace sfa30 {
6
7static const char *const TAG = "sfa30";
8
9static const uint16_t SFA30_CMD_GET_DEVICE_MARKING = 0xD060;
10static const uint16_t SFA30_CMD_START_CONTINUOUS_MEASUREMENTS = 0x0006;
11static 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
95 });
96}
97
98} // namespace sfa30
99} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message="unspecified")
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.
Definition component.cpp:72
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:39
sensor::Sensor * temperature_sensor_
Definition sfa30.h:30
void dump_config() override
Definition sfa30.cpp:41
sensor::Sensor * humidity_sensor_
Definition sfa30.h:29
sensor::Sensor * formaldehyde_sensor_
Definition sfa30.h:28
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
uint16_t temperature
Definition sun_gtil2.cpp:12