9static constexpr uint8_t C_M1106_CMD_GET_CO2[4] = {0x11, 0x01, 0x01, 0xED};
10static constexpr uint8_t C_M1106_CMD_SET_CO2_CALIB[6] = {0x11, 0x03, 0x03, 0x00, 0x00, 0x00};
11static constexpr uint8_t C_M1106_CMD_SET_CO2_CALIB_RESPONSE[4] = {0x16, 0x01, 0x03, 0xE6};
14static constexpr uint8_t C_M1106_CMD_SET_ABC_STATUS[10] = {0x11, 0x07, 0x10, 0x64, 0x00, 0x0F, 0x01, 0x90, 0x64, 0x00};
15static constexpr uint8_t C_M1106_CMD_SET_ABC_STATUS_RESPONSE[4] = {0x16, 0x01, 0x10, 0xD9};
17static constexpr uint8_t CM1106_ABC_FLAG_ENABLE = 0x0;
18static constexpr uint8_t CM1106_ABC_FLAG_DISABLE = 0x2;
21 for (
size_t i = 0; i <
len - 1; i++) {
28 uint8_t response[8] = {0};
29 if (!this->
cm1106_write_command_(C_M1106_CMD_GET_CO2,
sizeof(C_M1106_CMD_GET_CO2), response,
sizeof(response))) {
40 uint8_t response[8] = {0};
41 if (!this->
cm1106_write_command_(C_M1106_CMD_GET_CO2,
sizeof(C_M1106_CMD_GET_CO2), response,
sizeof(response))) {
42 ESP_LOGW(TAG,
"Reading data failed!");
47 if (response[0] != 0x16 || response[1] != 0x05 || response[2] != 0x01) {
48 ESP_LOGW(TAG,
"Unexpected response: %02X %02X %02X %02X", response[0], response[1], response[2], response[3]);
55 ESP_LOGW(TAG,
"Checksum doesn't match: 0x%02X!=0x%02X", response[7],
checksum);
60 const uint16_t ppm = response[3] << 8 | response[4];
61 const uint8_t
status = response[5];
63 ESP_LOGW(TAG,
"Preheating; CO₂=%uppm", ppm);
68 ESP_LOGW(TAG,
"Status: %02X",
status);
72 ESP_LOGD(TAG,
"CO₂=%uppm DF4=%02X", ppm, response[6]);
79 memcpy(cmd, C_M1106_CMD_SET_CO2_CALIB,
sizeof(cmd));
83 ESP_LOGD(TAG,
"Successfully calibrated sensor to %uppm", ppm);
88 ESP_LOGD(TAG,
"%sabling automatic baseline calibration", enabled ? LOG_STR_LITERAL(
"En") : LOG_STR_LITERAL(
"Dis"));
90 memcpy(cmd, C_M1106_CMD_SET_ABC_STATUS,
sizeof(cmd));
91 cmd[4] = enabled ? CM1106_ABC_FLAG_ENABLE : CM1106_ABC_FLAG_DISABLE;
96 ESP_LOGD(TAG,
"Successfully set ABC status");
101 uint8_t response[4] = {0};
103 ESP_LOGW(TAG,
"Command %02X failed", command[2]);
108 ESP_LOGW(TAG,
"Unexpected response: %02X %02X %02X %02X", response[0], response[1], response[2], response[3]);
115 size_t response_len) {
121 if (response ==
nullptr)
124 return this->
read_array(response, response_len);
128 ESP_LOGCONFIG(TAG,
"CM1106:");
132 " Automatic baseline calibration on boot: %s\n"
133 " ABC calibration cycle: %u days\n"
134 " ABC baseline: %uppm",
void mark_failed()
Mark this component as failed.
void status_set_warning()
bool status_comm_result(bool ok)
Clears the warning when ok, else sets it with message (default "Communication failed"); returns ok.
void status_clear_warning()
bool send_command_expect_ack_(const uint8_t *command, size_t command_len, const uint8_t *ack)
Sends a command and checks the sensor's four byte acknowledgement, updating the warning status.
void calibrate_zero(uint16_t ppm)
void abc_set_(bool enabled)
void dump_config() override
CM1106ABCLogic abc_boot_logic_
bool cm1106_write_command_(const uint8_t *command, size_t command_len, uint8_t *response, size_t response_len)
sensor::Sensor * co2_sensor_
void publish_state(float state)
Publish a new state to the front-end.
optional< std::array< uint8_t, N > > read_array()
void discard_available()
Read and drop every byte waiting in the receive buffer.
void write_byte(uint8_t data)
void write_array(const uint8_t *data, size_t len)
uint8_t cm1106_checksum(const uint8_t *response, size_t len)
ESPHOME_LOG_TAG(TAG, "cm1106")