ESPHome 2025.6.3
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 {
13namespace gcja5 {
14
15static const char *const TAG = "gcja5";
16
18 const uint32_t now = App.get_loop_component_start_time();
19 if (now - this->last_transmission_ >= 500) {
20 // last transmission too long ago. Reset RX index.
21 this->rx_message_.clear();
22 }
23
24 if (this->available() == 0) {
25 return;
26 }
27
28 // There must now be data waiting
29 this->last_transmission_ = now;
30 uint8_t val;
31 while (this->available() != 0) {
32 this->read_byte(&val);
33 this->rx_message_.push_back(val);
34
35 // check if rx_message_ has 32 bytes of data
36 if (this->rx_message_.size() == 32) {
37 this->parse_data_();
38
39 if (this->have_good_data_) {
40 if (this->pm_1_0_sensor_ != nullptr)
42 if (this->pm_2_5_sensor_ != nullptr)
44 if (this->pm_10_0_sensor_ != nullptr)
46 if (this->pmc_0_3_sensor_ != nullptr)
48 if (this->pmc_0_5_sensor_ != nullptr)
50 if (this->pmc_1_0_sensor_ != nullptr)
52 if (this->pmc_2_5_sensor_ != nullptr)
54 if (this->pmc_5_0_sensor_ != nullptr)
56 if (this->pmc_10_0_sensor_ != nullptr)
58 } else {
59 this->status_set_warning();
60 ESP_LOGV(TAG, "Have 32 bytes but not good data. Skipping.");
61 }
62
63 this->rx_message_.clear();
64 }
65 }
66}
67
69 uint8_t crc = 0;
70
71 for (uint8_t i = 1; i < 30; i++)
72 crc = crc ^ this->rx_message_[i];
73
74 ESP_LOGVV(TAG, "Checksum packet was (0x%02X), calculated checksum was (0x%02X)", this->rx_message_[30], crc);
75
76 return (crc == this->rx_message_[30]);
77}
78
80 ESP_LOGVV(TAG, "GCJA5 Data: ");
81 for (uint8_t i = 0; i < 32; i++) {
82 ESP_LOGVV(TAG, " %u: 0b" BYTE_TO_BINARY_PATTERN " (0x%02X)", i + 1, BYTE_TO_BINARY(this->rx_message_[i]),
83 this->rx_message_[i]);
84 }
85
86 if (this->rx_message_[0] != 0x02 || this->rx_message_[31] != 0x03 || !this->calculate_checksum_()) {
87 ESP_LOGVV(TAG, "Discarding bad packet - failed checks.");
88 return;
89 } else {
90 ESP_LOGVV(TAG, "Good packet found.");
91 }
92
93 this->have_good_data_ = true;
94 uint8_t status = this->rx_message_[29];
95 if (!this->first_status_log_) {
96 this->first_status_log_ = true;
97
98 ESP_LOGI(TAG, "GCJA5 Status");
99 ESP_LOGI(TAG, "Overall Status : %i", (status >> 6) & 0x03);
100 ESP_LOGI(TAG, "PD Status : %i", (status >> 4) & 0x03);
101 ESP_LOGI(TAG, "LD Status : %i", (status >> 2) & 0x03);
102 ESP_LOGI(TAG, "Fan Status : %i", (status >> 0) & 0x03);
103 }
104}
105
107
108} // namespace gcja5
109} // namespace esphome
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.
void status_set_warning(const char *message="unspecified")
uint32_t get_32_bit_uint_(uint8_t start_index) const
Definition gcja5.h:35
sensor::Sensor * pm_2_5_sensor_
Definition gcja5.h:45
uint16_t get_16_bit_uint_(uint8_t start_index) const
Definition gcja5.h:32
sensor::Sensor * pm_1_0_sensor_
Definition gcja5.h:44
sensor::Sensor * pmc_1_0_sensor_
Definition gcja5.h:50
sensor::Sensor * pmc_5_0_sensor_
Definition gcja5.h:52
sensor::Sensor * pmc_0_3_sensor_
Definition gcja5.h:48
sensor::Sensor * pmc_2_5_sensor_
Definition gcja5.h:51
sensor::Sensor * pmc_0_5_sensor_
Definition gcja5.h:49
sensor::Sensor * pmc_10_0_sensor_
Definition gcja5.h:53
sensor::Sensor * pm_10_0_sensor_
Definition gcja5.h:46
void dump_config() override
Definition gcja5.cpp:106
std::vector< uint8_t > rx_message_
Definition gcja5.h:40
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:39
bool read_byte(uint8_t *data)
Definition uart.h:29
mopeka_std_values val[4]
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
Application App
Global storage of Application pointer - only one Application can exist.