ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
gcja5.cpp
Go to the documentation of this file.
1/* From snooping with a logic analyzer, the I2C on this sensor is broken. I was only able
2 * to receive 1's as a response from the sensor. I was able to get the UART working.
3 *
4 * The datasheet says the values should be divided by 1000, but this must only be for the I2C
5 * implementation. Comparing UART values with another sensor, there is no need to divide by 1000.
6 */
7#include "gcja5.h"
8#include "esphome/core/log.h"
10#include <cstring>
11
12namespace esphome::gcja5 {
13
14static const char *const TAG = "gcja5";
15
18 if (now - this->last_transmission_ >= 500) {
19 // last transmission too long ago. Reset RX index.
20 this->rx_message_.clear();
21 }
22
23 if (this->available() == 0) {
24 return;
25 }
26
27 // There must now be data waiting
28 this->last_transmission_ = now;
29 uint8_t val;
30 while (this->available() != 0) {
31 this->read_byte(&val);
32 this->rx_message_.push_back(val);
33
34 // check if rx_message_ has 32 bytes of data
35 if (this->rx_message_.size() == 32) {
36 this->parse_data_();
37
38 if (this->have_good_data_) {
39 if (this->pm_1_0_sensor_ != nullptr)
41 if (this->pm_2_5_sensor_ != nullptr)
43 if (this->pm_10_0_sensor_ != nullptr)
45 if (this->pmc_0_3_sensor_ != nullptr)
47 if (this->pmc_0_5_sensor_ != nullptr)
49 if (this->pmc_1_0_sensor_ != nullptr)
51 if (this->pmc_2_5_sensor_ != nullptr)
53 if (this->pmc_5_0_sensor_ != nullptr)
55 if (this->pmc_10_0_sensor_ != nullptr)
57 } else {
58 this->status_set_warning();
59 ESP_LOGV(TAG, "Have 32 bytes but not good data. Skipping.");
60 }
61
62 this->rx_message_.clear();
63 }
64 }
65}
66
68 uint8_t crc = 0;
69
70 for (uint8_t i = 1; i < 30; i++)
71 crc = crc ^ this->rx_message_[i];
72
73 ESP_LOGVV(TAG, "Checksum packet was (0x%02X), calculated checksum was (0x%02X)", this->rx_message_[30], crc);
74
75 return (crc == this->rx_message_[30]);
76}
77
79 ESP_LOGVV(TAG, "GCJA5 Data: ");
80 for (uint8_t i = 0; i < 32; i++) {
81 ESP_LOGVV(TAG, " %u: 0b" BYTE_TO_BINARY_PATTERN " (0x%02X)", i + 1, BYTE_TO_BINARY(this->rx_message_[i]),
82 this->rx_message_[i]);
83 }
84
85 if (this->rx_message_[0] != 0x02 || this->rx_message_[31] != 0x03 || !this->calculate_checksum_()) {
86 ESP_LOGVV(TAG, "Discarding bad packet - failed checks.");
87 return;
88 } else {
89 ESP_LOGVV(TAG, "Good packet found.");
90 }
91
92 this->have_good_data_ = true;
93 uint8_t status = this->rx_message_[29];
94 if (!this->first_status_log_) {
95 this->first_status_log_ = true;
96
97 ESP_LOGI(TAG,
98 "GCJA5 Status\n"
99 " Overall Status : %i\n"
100 " PD Status : %i\n"
101 " LD Status : %i\n"
102 " Fan Status : %i",
103 (status >> 6) & 0x03, (status >> 4) & 0x03, (status >> 2) & 0x03, (status >> 0) & 0x03);
104 }
105}
106
108
109} // namespace esphome::gcja5
uint8_t status
Definition bl0942.h:8
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
uint32_t get_32_bit_uint_(uint8_t start_index) const
Definition gcja5.h:33
sensor::Sensor * pm_2_5_sensor_
Definition gcja5.h:43
uint16_t get_16_bit_uint_(uint8_t start_index) const
Definition gcja5.h:30
sensor::Sensor * pm_1_0_sensor_
Definition gcja5.h:42
sensor::Sensor * pmc_1_0_sensor_
Definition gcja5.h:48
sensor::Sensor * pmc_5_0_sensor_
Definition gcja5.h:50
sensor::Sensor * pmc_0_3_sensor_
Definition gcja5.h:46
sensor::Sensor * pmc_2_5_sensor_
Definition gcja5.h:49
sensor::Sensor * pmc_0_5_sensor_
Definition gcja5.h:47
sensor::Sensor * pmc_10_0_sensor_
Definition gcja5.h:51
sensor::Sensor * pm_10_0_sensor_
Definition gcja5.h:44
void dump_config() override
Definition gcja5.cpp:107
std::vector< uint8_t > rx_message_
Definition gcja5.h:38
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:68
bool read_byte(uint8_t *data)
Definition uart.h:34
mopeka_std_values val[3]
Application App
Global storage of Application pointer - only one Application can exist.
static void uint32_t