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