9static constexpr uint32_t REBOOT_INTERVAL_ID = 0;
11#define HYDREON_RGXX_COMMA ,
12static const char *
const PROTOCOL_NAMES[] = {HYDREON_RGXX_PROTOCOL_LIST(, HYDREON_RGXX_COMMA)};
13static const char *
const IGNORE_STRINGS[] = {HYDREON_RGXX_IGNORE_LIST(, HYDREON_RGXX_COMMA)};
16 ESP_LOGCONFIG(TAG,
"hydreon_rgxx:");
23 ESP_LOGCONFIG(TAG,
" Model: RG15");
25 ESP_LOGCONFIG(TAG,
" Resolution: high");
27 ESP_LOGCONFIG(TAG,
" Resolution: low");
30 LOG_UPDATE_INTERVAL(
this);
33#define HYDREON_RGXX_LOG_SENSOR(s) \
34 if (this->sensors_[i++] != nullptr) { \
35 LOG_SENSOR(" ", #s, this->sensors_[i - 1]); \
37 HYDREON_RGXX_PROTOCOL_LIST(HYDREON_RGXX_LOG_SENSOR, );
49 int ret = NUM_SENSORS;
50 for (
int i = 0; i < NUM_SENSORS; i++) {
65 for (
int i = 0; i < NUM_SENSORS; i++) {
70 ESP_LOGW(TAG,
"Missing %s", PROTOCOL_NAMES[i]);
77 ESP_LOGE(TAG,
"asking sensor to reboot");
78 for (
auto &sensor : this->
sensors_) {
79 if (sensor !=
nullptr) {
80 sensor->publish_state(NAN);
90#ifdef USE_BINARY_SENSOR
113 if (line !=
nullptr) {
137 ESP_LOGW(TAG,
"hydreon_rgxx failed to boot %d times", -this->
boot_count_);
142 ESP_LOGE(TAG,
"hydreon_rgxx can't boot, giving up");
143 for (
auto &sensor : this->
sensors_) {
144 if (sensor !=
nullptr) {
145 sensor->publish_state(NAN);
154 ESP_LOGV(TAG,
"Read from serial: %s", line.
c_str());
156 if (line[0] ==
';') {
157 ESP_LOGI(TAG,
"Comment: %s", line.
c_str());
161 ESP_LOGD(TAG,
"Received empty line");
164 if (line.
size() == 1) {
166 ESP_LOGD(TAG,
"Received ack: %s", line.
c_str());
169 if (line.
find(
"LensBad") != std::string::npos) {
170 ESP_LOGW(TAG,
"Received LensBad!");
173 if (line.
find(
"EmSat") != std::string::npos) {
174 ESP_LOGW(TAG,
"Received EmSat!");
185 ESP_LOGI(TAG,
"Boot detected: %s", line.
c_str());
209 if (majend == std::string::npos || endversion == std::string::npos || majend > endversion) {
210 ESP_LOGW(TAG,
"invalid version string: %s", line.
c_str());
213 int major = line.
size() > 3 ? strtol(line.
c_str() + 3,
nullptr, 10) : 0;
214 int minor = strtol(line.
c_str() + (majend == std::string::npos ? 0 : majend + 1),
nullptr, 10);
216 if (major > 10 || minor >= 1000 || minor < 0 || major < 0) {
217 ESP_LOGW(TAG,
"invalid version: %s", line.
c_str());
220 ESP_LOGI(TAG,
"detected sw version %i", this->
sw_version_);
223 bool is_data_line =
false;
224 for (
int i = 0; i < NUM_SENSORS; i++) {
229 if (n == std::string::npos) {
234 if (n == line.
find(
't', n)) {
238 n = line.
find(
'F', n);
239 if (n == std::string::npos) {
244 n += strlen(PROTOCOL_NAMES[i]);
248 float data = strtof(line.
c_str() + n,
nullptr);
250 ESP_LOGD(TAG,
"Received %s: %f", PROTOCOL_NAMES[i], this->
sensors_[i]->get_raw_state());
255 this->
too_cold_ |= tc != std::string::npos;
257 ESP_LOGD(TAG,
"Received TooCold");
263 for (
const auto *ignore : IGNORE_STRINGS) {
265 ESP_LOGI(TAG,
"Ignoring %s", line.
c_str());
269 ESP_LOGI(TAG,
"Got unknown line: %s", line.
c_str());
void mark_failed()
Mark this component as failed.
bool cancel_interval(const char *name)
Cancel an interval function.
void set_interval(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a const char* name.
char * feed(uint8_t c)
Feed one byte; returns the completed line (empty lines included), valid until the next call,...
void log_if_overflowed(const char *tag) const
Log the shared "line dropped" warning when the last feed() overflowed.
StringRef is a reference to a string owned by something else.
constexpr const char * c_str() const
size_type find(const char *s, size_type pos=0) const
Find first occurrence of substring, returns std::string::npos if not found.
bool starts_with(const StringRef &prefix) const
True if the view begins with the given prefix (std::string::starts_with-like)
constexpr bool empty() const
constexpr size_type size() const
std::allocator_traits< allocator_type >::size_type size_type
void publish_state(bool new_state)
Publish a new state to the front-end.
void update() override
Schedule data readings.
void setup() override
Setup the sensor and test for a connection.
binary_sensor::BinarySensor * em_sat_sensor_
binary_sensor::BinarySensor * lens_bad_sensor_
int16_t no_response_count_
int num_sensors_missing_()
void process_line_(StringRef line)
line is NUL terminated
bool request_temperature_
LineReader< 80 > line_reader_
void schedule_reboot_()
Communication with the sensor is asynchronous.
RG15Resolution resolution_
binary_sensor::BinarySensor * too_cold_sensor_
void loop() override
Read data once available.
sensor::Sensor * sensors_[NUM_SENSORS]
void dump_config() override
void publish_state(float state)
Publish a new state to the front-end.
void discard_available()
Read and drop every byte waiting in the receive buffer.
void write_str(const char *str)
bool read_available(F &&on_byte)
Same as read_available_chunks(), calling on_byte(uint8_t) once per byte.
ESPHOME_LOG_TAG(TAG, "hydreon_rgxx.sensor")