ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
gdk101.cpp
Go to the documentation of this file.
1#include "gdk101.h"
2#include "esphome/core/hal.h"
3#include "esphome/core/log.h"
4
5namespace esphome::gdk101 {
6
7ESPHOME_LOG_TAG(TAG, "gdk101");
8static constexpr uint8_t NUMBER_OF_READ_RETRIES = 5;
9static constexpr uint8_t NUMBER_OF_RESET_RETRIES = 30;
10static constexpr uint32_t RESET_INTERVAL_ID = 0;
11static constexpr uint32_t RESET_INTERVAL_MS = 1000;
12
13void GDK101Component::update() {
14 if (!this->reset_complete_)
15 return;
16
17 uint8_t data[2];
18 if (!this->read_dose_1m_(data)) {
19 this->status_set_warning(LOG_STR("Failed to read dose 1m"));
20 return;
21 }
22
23 if (!this->read_dose_10m_(data)) {
24 this->status_set_warning(LOG_STR("Failed to read dose 10m"));
25 return;
26 }
27
28 if (!this->read_status_(data)) {
29 this->status_set_warning(LOG_STR("Failed to read status"));
30 return;
31 }
32
33 this->status_comm_result(this->read_measurement_duration_(data), LOG_STR("Failed to read measurement duration"));
34}
35
37 if (!this->try_reset_()) {
38 // Sensor MCU boots slowly after power cycle — retry on a short interval
39 this->reset_retries_remaining_ = NUMBER_OF_RESET_RETRIES;
40 this->set_interval(RESET_INTERVAL_ID, RESET_INTERVAL_MS, [this]() {
41 if (this->try_reset_()) {
42 if (this->reset_complete_) {
43 this->update();
44 }
45 return;
46 }
47 if (--this->reset_retries_remaining_ == 0) {
48 this->cancel_interval(RESET_INTERVAL_ID);
49 this->mark_failed(LOG_STR("Reset failed after retries"));
50 }
51 });
52 }
53}
54
57 uint8_t data[2] = {0};
58 if (!this->reset_sensor_(data)) {
59 this->status_set_warning(LOG_STR("Sensor not answering reset, will retry"));
60 return false;
61 }
62 if (data[0] != 1) {
63 this->status_set_warning(LOG_STR("Reset not acknowledged, will retry"));
64 return false;
65 }
66 delay(10);
67 if (!this->read_fw_version_(data)) {
68 this->cancel_interval(RESET_INTERVAL_ID);
69 this->mark_failed(LOG_STR("Failed to read firmware version"));
70 return true;
71 }
72 this->reset_complete_ = true;
74 this->cancel_interval(RESET_INTERVAL_ID);
75 return true;
76}
77
78void GDK101Component::dump_config() {
79 ESP_LOGCONFIG(TAG, "GDK101:");
80 LOG_I2C_DEVICE(this);
81#ifdef USE_SENSOR
82 LOG_SENSOR(" ", "Average Radaition Dose per 1 minute", this->rad_1m_sensor_);
83 LOG_SENSOR(" ", "Average Radaition Dose per 10 minutes", this->rad_10m_sensor_);
84 LOG_SENSOR(" ", "Status", this->status_sensor_);
85 LOG_SENSOR(" ", "Measurement Duration", this->measurement_duration_sensor_);
86#endif // USE_SENSOR
87
88#ifdef USE_BINARY_SENSOR
89 LOG_BINARY_SENSOR(" ", "Vibration Status", this->vibration_binary_sensor_);
90#endif // USE_BINARY_SENSOR
91
92#ifdef USE_TEXT_SENSOR
93 LOG_TEXT_SENSOR(" ", "Firmware Version", this->fw_version_text_sensor_);
94#endif // USE_TEXT_SENSOR
95}
96
97bool GDK101Component::read_bytes_with_retry_(uint8_t a_register, uint8_t *data, uint8_t len) {
98 uint8_t retry = NUMBER_OF_READ_RETRIES;
99 bool status = false;
100 while (!status && retry) {
101 status = this->read_bytes(a_register, data, len);
102 retry--;
103 }
104 return status;
105}
106
108 // It looks like reset is not so well designed in that sensor
109 // After sending reset command it looks that sensor start performing reset and is unresponsible during read
110 // after a while we can send another reset command and read "0x01" as confirmation
111 // Documentation not going in to such details unfortunately
112 return this->read_bytes_with_retry_(GDK101_REG_RESET, data, 2);
113}
114
116#ifdef USE_SENSOR
117 if (this->rad_1m_sensor_ != nullptr) {
118 if (!this->read_bytes(GDK101_REG_READ_1MIN_AVG, data, 2)) {
119 ESP_LOGE(TAG, "Updating GDK101 failed!");
120 return false;
121 }
122
123 const float dose = data[0] + (data[1] / 100.0f);
124
125 this->rad_1m_sensor_->publish_state(dose);
126 }
127#endif // USE_SENSOR
128 return true;
129}
130
132#ifdef USE_SENSOR
133 if (this->rad_10m_sensor_ != nullptr) {
134 if (!this->read_bytes(GDK101_REG_READ_10MIN_AVG, data, 2)) {
135 ESP_LOGE(TAG, "Updating GDK101 failed!");
136 return false;
137 }
138
139 const float dose = data[0] + (data[1] / 100.0f);
140
141 this->rad_10m_sensor_->publish_state(dose);
142 }
143#endif // USE_SENSOR
144 return true;
145}
146
147bool GDK101Component::read_status_(uint8_t *data) {
148 if (!this->read_bytes(GDK101_REG_READ_STATUS, data, 2)) {
149 ESP_LOGE(TAG, "Updating GDK101 failed!");
150 return false;
151 }
152
153#ifdef USE_SENSOR
154 if (this->status_sensor_ != nullptr) {
155 this->status_sensor_->publish_state(data[0]);
156 }
157#endif // USE_SENSOR
158
159#ifdef USE_BINARY_SENSOR
160 if (this->vibration_binary_sensor_ != nullptr) {
161 this->vibration_binary_sensor_->publish_state(data[1]);
162 }
163#endif // USE_BINARY_SENSOR
164
165 return true;
166}
167
169#ifdef USE_TEXT_SENSOR
170 if (this->fw_version_text_sensor_ != nullptr) {
171 if (!this->read_bytes(GDK101_REG_READ_FIRMWARE, data, 2)) {
172 ESP_LOGE(TAG, "Updating GDK101 failed!");
173 return false;
174 }
175
176 // max 8: "255.255" (7 chars) + null
177 char buf[8];
178 snprintf(buf, sizeof(buf), "%d.%d", data[0], data[1]);
179 this->fw_version_text_sensor_->publish_state(buf);
180 }
181#endif // USE_TEXT_SENSOR
182 return true;
183}
184
186#ifdef USE_SENSOR
187 if (this->measurement_duration_sensor_ != nullptr) {
188 if (!this->read_bytes(GDK101_REG_READ_MEASURING_TIME, data, 2)) {
189 ESP_LOGE(TAG, "Updating GDK101 failed!");
190 return false;
191 }
192
193 const float meas_time = (data[0] * 60) + data[1];
194
195 this->measurement_duration_sensor_->publish_state(meas_time);
196 }
197#endif // USE_SENSOR
198 return true;
199}
200
201} // namespace esphome::gdk101
uint8_t status
Definition bl0942.h:8
void mark_failed()
Mark this component as failed.
virtual void setup()
Where the component's initialization should happen.
Definition component.cpp:84
bool cancel_interval(const char *name)
Cancel an interval function.
Definition component.cpp:92
bool status_comm_result(bool ok)
Clears the warning when ok, else sets it with message (default "Communication failed"); returns ok.
void set_interval(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a const char* name.
Definition component.cpp:88
void status_clear_warning()
Definition component.h:296
bool try_reset_()
Attempt to reset the sensor and read firmware version. Returns true on success or hard failure.
Definition gdk101.cpp:56
bool read_status_(uint8_t *data)
Definition gdk101.cpp:147
bool read_bytes_with_retry_(uint8_t a_register, uint8_t *data, uint8_t len)
Definition gdk101.cpp:97
bool read_dose_1m_(uint8_t *data)
Definition gdk101.cpp:115
bool read_dose_10m_(uint8_t *data)
Definition gdk101.cpp:131
bool read_fw_version_(uint8_t *data)
Definition gdk101.cpp:168
bool reset_sensor_(uint8_t *data)
Definition gdk101.cpp:107
bool read_measurement_duration_(uint8_t *data)
Definition gdk101.cpp:185
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
Definition i2c.h:249
ESPHOME_LOG_TAG(TAG, "gdk101")
const void size_t len
Definition hal.h:68
void HOT delay(uint32_t ms)
Definition hal.cpp:85
static void uint32_t