7static const char *
const TAG =
"sfa40";
11static const uint16_t SFA40_CMD_START_MEASUREMENT = 0x00AC;
12static const uint16_t SFA40_CMD_STOP_MEASUREMENT = 0x50D2;
13static const uint16_t SFA40_CMD_READ_MEASURE_PROD = 0xC0EB;
15static const uint16_t SFA40_CMD_READ_MEASURE_B4 = 0xE06D;
16static const uint16_t SFA40_CMD_READ_ID_PROD = 0x02CE;
17static const uint16_t SFA40_CMD_READ_ID_B4 = 0x0559;
18static const uint8_t STATUS_NOT_READY = 0x01;
19static const uint8_t STATUS_OUT_OF_SPEC = 0x02;
21static uint64_t raw_to_serial(
const uint16_t *
raw,
size_t words) {
23 for (
size_t i = 0; i < words; i++) {
24 serial = (serial << 16) |
raw[i];
29static void raw_to_marking(
const uint16_t *
raw,
size_t words,
char *out,
size_t out_len) {
30 if (out_len < words * 2 + 1) {
33 for (
size_t i = 0; i < words; i++) {
34 out[i * 2] =
static_cast<char>(
raw[i] >> 8);
35 out[i * 2 + 1] =
static_cast<char>(
raw[i] & 0xFF);
37 out[words * 2] =
'\0';
44 ESP_LOGE(TAG,
"Failed to detect SFA40 protocol");
50 ESP_LOGE(TAG,
"Failed to start measurements");
56 ESP_LOGD(TAG,
"Measurement started");
65 ESP_LOGD(TAG,
"Detected production SFA40, serial number: %012" PRIX64, this->
serial_number_);
71 ESP_LOGD(TAG,
"Detected engineering-sample SFA40, marking: '%s'", this->
device_marking_);
78 ESP_LOGCONFIG(TAG,
"sfa40:");
83 ESP_LOGW(TAG,
"Protocol detection failed!");
86 ESP_LOGW(TAG,
"Measurement initialization failed!");
89 ESP_LOGW(TAG,
"Unknown setup error!");
93 LOG_UPDATE_INTERVAL(
this);
96 ESP_LOGCONFIG(TAG,
" Protocol: production\n Serial Number: %012" PRIX64, this->
serial_number_);
99 ESP_LOGCONFIG(TAG,
" Protocol: prototype (B4)\n Marking: '%s'", this->
device_marking_);
102 ESP_LOGCONFIG(TAG,
" Protocol: (detecting...)");
105 ESP_LOGCONFIG(TAG,
" Wait for ready: %s", YESNO(this->
wait_for_ready_));
117 : SFA40_CMD_READ_MEASURE_B4;
120 ESP_LOGW(TAG,
"Error reading measurement");
128 ESP_LOGW(TAG,
"Error reading measurement data");
134 const bool sensor_not_ready = (
status & STATUS_NOT_READY) != 0;
135 const bool sensor_out_of_spec = (
status & STATUS_OUT_OF_SPEC) != 0;
138 if (sensor_out_of_spec) {
139 ESP_LOGW(TAG,
"Skipping formaldehyde publish: sensor out of spec (status=0x%02X)",
status);
141 ESP_LOGD(TAG,
"Skipping formaldehyde publish: sensor warming up");
void mark_failed()
Mark this component as failed.
void status_set_warning()
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
void status_clear_warning()
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.
sensor::Sensor * temperature_sensor_
void dump_config() override
sensor::Sensor * humidity_sensor_
ProtocolVersion protocol_version_
@ MEASUREMENT_INIT_FAILED
@ PROTOCOL_DETECTION_FAILED
sensor::Sensor * formaldehyde_sensor_