ESPHome 2025.9.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
37 if (this->read(data_buffer_, 29) != i2c::ERROR_OK) {
38 ESP_LOGW(TAG, "Read result failed");
39 this->status_set_warning();
40 return;
41 }
42
43 if (!this->validate_checksum_(data_buffer_)) {
44 ESP_LOGW(TAG, "Checksum validation failed");
45 this->status_set_warning();
46 return;
47 }
48
49 int16_t pm_1_0_value = -1;
50 if (this->pm_1_0_sensor_ != nullptr) {
51 pm_1_0_value = get_sensor_value_(data_buffer_, PM_1_0_VALUE_INDEX);
52 }
53
54 int16_t pm_2_5_value = -1;
55 if (this->pm_2_5_sensor_ != nullptr) {
56 pm_2_5_value = get_sensor_value_(data_buffer_, PM_2_5_VALUE_INDEX);
57 }
58
59 int16_t pm_10_0_value = -1;
60 if (this->pm_10_0_sensor_ != nullptr) {
61 pm_10_0_value = get_sensor_value_(data_buffer_, PM_10_0_VALUE_INDEX);
62 }
63
64 int16_t aqi_value = -1;
65 if (this->aqi_sensor_ != nullptr && pm_2_5_value != -1 && pm_10_0_value != -1) {
67 aqi_value = calculator->get_aqi(pm_2_5_value, pm_10_0_value);
68 }
69
70 if (pm_1_0_value != -1) {
71 this->pm_1_0_sensor_->publish_state(pm_1_0_value);
72 }
73 if (pm_2_5_value != -1) {
74 this->pm_2_5_sensor_->publish_state(pm_2_5_value);
75 }
76 if (pm_10_0_value != -1) {
77 this->pm_10_0_sensor_->publish_state(pm_10_0_value);
78 }
79 if (aqi_value != -1) {
80 this->aqi_sensor_->publish_state(aqi_value);
81 }
82
84}
85
86bool HM3301Component::validate_checksum_(const uint8_t *data) {
87 uint8_t sum = 0;
88 for (int i = 0; i < 28; i++) {
89 sum += data[i];
90 }
91
92 return sum == data[28];
93}
94
95uint16_t HM3301Component::get_sensor_value_(const uint8_t *data, uint8_t i) {
96 return (uint16_t) data[i * 2] << 8 | data[i * 2 + 1];
97}
98
99} // namespace hm3301
100} // namespace esphome
virtual 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(uint16_t pm2_5_value, uint16_t pm10_0_value)=0
AQICalculatorType aqi_calc_type_
Definition hm3301.h:44
uint16_t get_sensor_value_(const uint8_t *data, uint8_t i)
Definition hm3301.cpp:95
float get_setup_priority() const override
Definition hm3301.cpp:34
sensor::Sensor * aqi_sensor_
Definition hm3301.h:42
sensor::Sensor * pm_1_0_sensor_
Definition hm3301.h:39
sensor::Sensor * pm_2_5_sensor_
Definition hm3301.h:40
AQICalculatorFactory aqi_calculator_factory_
Definition hm3301.h:45
sensor::Sensor * pm_10_0_sensor_
Definition hm3301.h:41
bool validate_checksum_(const uint8_t *data)
Definition hm3301.cpp:86
ErrorCode write(const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a device using an I2CBus
Definition i2c.h:190
ErrorCode read(uint8_t *data, size_t len)
reads an array of bytes from the device using an I2CBus
Definition i2c.h:164
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:45
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:13
const float DATA
For components that import data from directly connected sensors like DHT.
Definition component.cpp:50
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7