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