ESPHome 2026.3.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 {
5namespace hm3301 {
6
7static const char *const TAG = "hm3301.sensor";
8
9static const uint8_t PM_1_0_VALUE_INDEX = 5;
10static const uint8_t PM_2_5_VALUE_INDEX = 6;
11static const uint8_t PM_10_0_VALUE_INDEX = 7;
12
14 if (i2c::ERROR_OK != this->write(&SELECT_COMM_CMD, 1)) {
15 error_code_ = ERROR_COMM;
16 this->mark_failed();
17 return;
18 }
19}
20
22 ESP_LOGCONFIG(TAG, "HM3301:");
23 LOG_I2C_DEVICE(this);
24 if (error_code_ == ERROR_COMM) {
25 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
26 }
27
28 LOG_SENSOR(" ", "PM1.0", this->pm_1_0_sensor_);
29 LOG_SENSOR(" ", "PM2.5", this->pm_2_5_sensor_);
30 LOG_SENSOR(" ", "PM10.0", this->pm_10_0_sensor_);
31 LOG_SENSOR(" ", "AQI", this->aqi_sensor_);
32}
33
35 if (this->read(data_buffer_, 29) != i2c::ERROR_OK) {
36 ESP_LOGW(TAG, "Read result failed");
37 this->status_set_warning();
38 return;
39 }
40
41 if (!this->validate_checksum_(data_buffer_)) {
42 ESP_LOGW(TAG, "Checksum validation failed");
43 this->status_set_warning();
44 return;
45 }
46
47 int16_t pm_1_0_value = -1;
48 if (this->pm_1_0_sensor_ != nullptr) {
49 pm_1_0_value = get_sensor_value_(data_buffer_, PM_1_0_VALUE_INDEX);
50 }
51
52 int16_t pm_2_5_value = -1;
53 if (this->pm_2_5_sensor_ != nullptr) {
54 pm_2_5_value = get_sensor_value_(data_buffer_, PM_2_5_VALUE_INDEX);
55 }
56
57 int16_t pm_10_0_value = -1;
58 if (this->pm_10_0_sensor_ != nullptr) {
59 pm_10_0_value = get_sensor_value_(data_buffer_, PM_10_0_VALUE_INDEX);
60 }
61
62 int16_t aqi_value = -1;
63 if (this->aqi_sensor_ != nullptr && pm_2_5_value != -1 && pm_10_0_value != -1) {
65 aqi_value = calculator->get_aqi(pm_2_5_value, pm_10_0_value);
66 }
67
68 if (pm_1_0_value != -1) {
69 this->pm_1_0_sensor_->publish_state(pm_1_0_value);
70 }
71 if (pm_2_5_value != -1) {
72 this->pm_2_5_sensor_->publish_state(pm_2_5_value);
73 }
74 if (pm_10_0_value != -1) {
75 this->pm_10_0_sensor_->publish_state(pm_10_0_value);
76 }
77 if (aqi_value != -1) {
78 this->aqi_sensor_->publish_state(aqi_value);
79 }
80
82}
83
84bool HM3301Component::validate_checksum_(const uint8_t *data) {
85 uint8_t sum = 0;
86 for (int i = 0; i < 28; i++) {
87 sum += data[i];
88 }
89
90 return sum == data[28];
91}
92
93uint16_t HM3301Component::get_sensor_value_(const uint8_t *data, uint8_t i) {
94 return (uint16_t) data[i * 2] << 8 | data[i * 2 + 1];
95}
96
97} // namespace hm3301
98} // namespace esphome
void mark_failed()
Mark this component as failed.
void status_set_warning(const char *message=nullptr)
void status_clear_warning()
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:93
sensor::Sensor * aqi_sensor_
Definition hm3301.h:41
sensor::Sensor * pm_1_0_sensor_
Definition hm3301.h:38
aqi::AQICalculatorFactory aqi_calculator_factory_
Definition hm3301.h:44
sensor::Sensor * pm_2_5_sensor_
Definition hm3301.h:39
aqi::AQICalculatorType aqi_calc_type_
Definition hm3301.h:43
sensor::Sensor * pm_10_0_sensor_
Definition hm3301.h:40
bool validate_checksum_(const uint8_t *data)
Definition hm3301.cpp:84
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:65
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:14
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7