ESPHome 2026.11.0-dev
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
14ESPHOME_LOG_TAG(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 const size_t avail = this->available();
24 if (avail == 0) {
25 return;
26 }
27
28 // There must now be data waiting
29 this->last_transmission_ = now;
30 this->read_available(
31 [this](uint8_t 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 avail);
66}
67
69 uint8_t crc = xor_bytes(&this->rx_message_[1], 29);
70
71 ESP_LOGVV(TAG, "Checksum packet was (0x%02X), calculated checksum was (0x%02X)", this->rx_message_[30], crc);
72
73 return (crc == this->rx_message_[30]);
74}
75
77 ESP_LOGVV(TAG, "GCJA5 Data: ");
78 for (uint8_t i = 0; i < 32; i++) {
79 ESP_LOGVV(TAG, " %u: 0b" BYTE_TO_BINARY_PATTERN " (0x%02X)", i + 1, BYTE_TO_BINARY(this->rx_message_[i]),
80 this->rx_message_[i]);
81 }
82
83 if (this->rx_message_[0] != 0x02 || this->rx_message_[31] != 0x03 || !this->calculate_checksum_()) {
84 ESP_LOGVV(TAG, "Discarding bad packet - failed checks.");
85 return;
86 } else {
87 ESP_LOGVV(TAG, "Good packet found.");
88 }
89
90 this->have_good_data_ = true;
91 uint8_t status = this->rx_message_[29];
92 if (!this->first_status_log_) {
93 this->first_status_log_ = true;
94
95 ESP_LOGI(TAG,
96 "GCJA5 Status\n"
97 " Overall Status : %i\n"
98 " PD Status : %i\n"
99 " LD Status : %i\n"
100 " Fan Status : %i",
101 (status >> 6) & 0x03, (status >> 4) & 0x03, (status >> 2) & 0x03, (status >> 0) & 0x03);
102 }
103}
104
106
107} // 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:105
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:65
bool read_available(F &&on_byte)
Same as read_available_chunks(), calling on_byte(uint8_t) once per byte.
Definition uart.h:77
mopeka_std_values val[3]
ESPHOME_LOG_TAG(TAG, "gcja5")
constexpr uint8_t xor_bytes(const uint8_t *data, size_t len, uint8_t init=0)
XOR the bytes of data with size len, starting from init.
Definition helpers.h:904
Application App
Global storage of Application pointer - only one Application can exist.
static void uint32_t