ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
hm3301.cpp
Go to the documentation of this file.
1#include "esphome/core/log.h"
2#include "hm3301.h"
3
4namespace esphome::hm3301 {
5
6static const char *const TAG = "hm3301.sensor";
7
8static const uint8_t PM_1_0_VALUE_INDEX = 5;
9static const uint8_t PM_2_5_VALUE_INDEX = 6;
10static const uint8_t PM_10_0_VALUE_INDEX = 7;
11
13 if (i2c::ERROR_OK != this->write(&SELECT_COMM_CMD, 1)) {
14 error_code_ = ERROR_COMM;
15 this->mark_failed();
16 return;
17 }
18}
19
21 ESP_LOGCONFIG(TAG, "HM3301:");
22 LOG_I2C_DEVICE(this);
23 if (error_code_ == ERROR_COMM) {
24 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
25 }
26
27 LOG_SENSOR(" ", "PM1.0", this->pm_1_0_sensor_);
28 LOG_SENSOR(" ", "PM2.5", this->pm_2_5_sensor_);
29 LOG_SENSOR(" ", "PM10.0", this->pm_10_0_sensor_);
30 LOG_SENSOR(" ", "AQI", this->aqi_sensor_);
31}
32
34 if (this->read(data_buffer_, 29) != i2c::ERROR_OK) {
35 ESP_LOGW(TAG, "Read result failed");
36 this->status_set_warning();
37 return;
38 }
39
40 if (!this->validate_checksum_(data_buffer_)) {
41 ESP_LOGW(TAG, "Checksum validation failed");
42 this->status_set_warning();
43 return;
44 }
45
46 int16_t pm_1_0_value = -1;
47 if (this->pm_1_0_sensor_ != nullptr) {
48 pm_1_0_value = get_sensor_value_(data_buffer_, PM_1_0_VALUE_INDEX);
49 }
50
51 int16_t pm_2_5_value = -1;
52 if (this->pm_2_5_sensor_ != nullptr) {
53 pm_2_5_value = get_sensor_value_(data_buffer_, PM_2_5_VALUE_INDEX);
54 }
55
56 int16_t pm_10_0_value = -1;
57 if (this->pm_10_0_sensor_ != nullptr) {
58 pm_10_0_value = get_sensor_value_(data_buffer_, PM_10_0_VALUE_INDEX);
59 }
60
61 int16_t aqi_value = -1;
62 if (this->aqi_sensor_ != nullptr && pm_2_5_value != -1 && pm_10_0_value != -1) {
64 aqi_value = calculator->get_aqi(pm_2_5_value, pm_10_0_value);
65 }
66
67 if (pm_1_0_value != -1) {
68 this->pm_1_0_sensor_->publish_state(pm_1_0_value);
69 }
70 if (pm_2_5_value != -1) {
71 this->pm_2_5_sensor_->publish_state(pm_2_5_value);
72 }
73 if (pm_10_0_value != -1) {
74 this->pm_10_0_sensor_->publish_state(pm_10_0_value);
75 }
76 if (aqi_value != -1) {
77 this->aqi_sensor_->publish_state(aqi_value);
78 }
79
81}
82
83bool HM3301Component::validate_checksum_(const uint8_t *data) {
84 uint8_t sum = 0;
85 for (int i = 0; i < 28; i++) {
86 sum += data[i];
87 }
88
89 return sum == data[28];
90}
91
92uint16_t HM3301Component::get_sensor_value_(const uint8_t *data, uint8_t i) {
93 return (uint16_t) data[i * 2] << 8 | data[i * 2 + 1];
94}
95
96} // namespace esphome::hm3301
void mark_failed()
Mark this component as failed.
void status_clear_warning()
Definition component.h:289
AbstractAQICalculator * get_calculator(AQICalculatorType type)
virtual uint16_t get_aqi(float pm2_5_value, float pm10_0_value)=0
uint16_t get_sensor_value_(const uint8_t *data, uint8_t i)
Definition hm3301.cpp:92
sensor::Sensor * aqi_sensor_
Definition hm3301.h:40
sensor::Sensor * pm_1_0_sensor_
Definition hm3301.h:37
aqi::AQICalculatorFactory aqi_calculator_factory_
Definition hm3301.h:43
sensor::Sensor * pm_2_5_sensor_
Definition hm3301.h:38
aqi::AQICalculatorType aqi_calc_type_
Definition hm3301.h:42
sensor::Sensor * pm_10_0_sensor_
Definition hm3301.h:39
bool validate_checksum_(const uint8_t *data)
Definition hm3301.cpp:83
ErrorCode write(const uint8_t *data, size_t len) const
writes an array of bytes to a device using an I2CBus
Definition i2c.h:183
ErrorCode read(uint8_t *data, size_t len) const
reads an array of bytes from the device using an I2CBus
Definition i2c.h:163
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:68
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:14