mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 09:01:49 +00:00 
			
		
		
		
	[ld2420] Memory optimization, code clean-up (#9426)
This commit is contained in:
		
				
					committed by
					
						
						Jesse Hills
					
				
			
			
				
	
			
			
			
						parent
						
							18787b0be0
						
					
				
				
					commit
					097aac2183
				
			@@ -5,10 +5,10 @@
 | 
			
		||||
namespace esphome {
 | 
			
		||||
namespace ld2420 {
 | 
			
		||||
 | 
			
		||||
static const char *const TAG = "LD2420.binary_sensor";
 | 
			
		||||
static const char *const TAG = "ld2420.binary_sensor";
 | 
			
		||||
 | 
			
		||||
void LD2420BinarySensor::dump_config() {
 | 
			
		||||
  ESP_LOGCONFIG(TAG, "LD2420 BinarySensor:");
 | 
			
		||||
  ESP_LOGCONFIG(TAG, "Binary Sensor:");
 | 
			
		||||
  LOG_BINARY_SENSOR("  ", "Presence", this->presence_bsensor_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
#include "esphome/core/helpers.h"
 | 
			
		||||
#include "esphome/core/log.h"
 | 
			
		||||
 | 
			
		||||
static const char *const TAG = "LD2420.button";
 | 
			
		||||
static const char *const TAG = "ld2420.button";
 | 
			
		||||
 | 
			
		||||
namespace esphome {
 | 
			
		||||
namespace ld2420 {
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ static const std::string OP_SIMPLE_MODE_STRING = "Simple";
 | 
			
		||||
// Memory-efficient lookup tables
 | 
			
		||||
struct StringToUint8 {
 | 
			
		||||
  const char *str;
 | 
			
		||||
  uint8_t value;
 | 
			
		||||
  const uint8_t value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static constexpr StringToUint8 OP_MODE_BY_STR[] = {
 | 
			
		||||
@@ -155,9 +155,10 @@ static constexpr const char *ERR_MESSAGE[] = {
 | 
			
		||||
// Helper function for lookups
 | 
			
		||||
template<size_t N> uint8_t find_uint8(const StringToUint8 (&arr)[N], const std::string &str) {
 | 
			
		||||
  for (const auto &entry : arr) {
 | 
			
		||||
    if (str == entry.str)
 | 
			
		||||
    if (str == entry.str) {
 | 
			
		||||
      return entry.value;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return 0xFF;  // Not found
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -326,15 +327,8 @@ void LD2420Component::revert_config_action() {
 | 
			
		||||
 | 
			
		||||
void LD2420Component::loop() {
 | 
			
		||||
  // If there is a active send command do not process it here, the send command call will handle it.
 | 
			
		||||
  if (!this->get_cmd_active_()) {
 | 
			
		||||
    if (!this->available())
 | 
			
		||||
      return;
 | 
			
		||||
    static uint8_t buffer[2048];
 | 
			
		||||
    static uint8_t rx_data;
 | 
			
		||||
    while (this->available()) {
 | 
			
		||||
      rx_data = this->read();
 | 
			
		||||
      this->readline_(rx_data, buffer, sizeof(buffer));
 | 
			
		||||
    }
 | 
			
		||||
  while (!this->cmd_active_ && this->available()) {
 | 
			
		||||
    this->readline_(this->read(), this->buffer_data_, MAX_LINE_LENGTH);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -365,8 +359,9 @@ void LD2420Component::auto_calibrate_sensitivity() {
 | 
			
		||||
 | 
			
		||||
    // Store average and peak values
 | 
			
		||||
    this->gate_avg[gate] = sum / CALIBRATE_SAMPLES;
 | 
			
		||||
    if (this->gate_peak[gate] < peak)
 | 
			
		||||
    if (this->gate_peak[gate] < peak) {
 | 
			
		||||
      this->gate_peak[gate] = peak;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t calculated_value =
 | 
			
		||||
        (static_cast<uint32_t>(this->gate_peak[gate]) + (move_factor * static_cast<uint32_t>(this->gate_peak[gate])));
 | 
			
		||||
@@ -403,8 +398,9 @@ void LD2420Component::set_operating_mode(const std::string &state) {
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      // Set the current data back so we don't have new data that can be applied in error.
 | 
			
		||||
      if (this->get_calibration_())
 | 
			
		||||
      if (this->get_calibration_()) {
 | 
			
		||||
        memcpy(&this->new_config, &this->current_config, sizeof(this->current_config));
 | 
			
		||||
      }
 | 
			
		||||
      this->set_calibration_(false);
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
@@ -414,30 +410,32 @@ void LD2420Component::set_operating_mode(const std::string &state) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LD2420Component::readline_(int rx_data, uint8_t *buffer, int len) {
 | 
			
		||||
  static int pos = 0;
 | 
			
		||||
 | 
			
		||||
  if (rx_data >= 0) {
 | 
			
		||||
    if (pos < len - 1) {
 | 
			
		||||
      buffer[pos++] = rx_data;
 | 
			
		||||
      buffer[pos] = 0;
 | 
			
		||||
  if (rx_data < 0) {
 | 
			
		||||
    return;  // No data available
 | 
			
		||||
  }
 | 
			
		||||
  if (this->buffer_pos_ < len - 1) {
 | 
			
		||||
    buffer[this->buffer_pos_++] = rx_data;
 | 
			
		||||
    buffer[this->buffer_pos_] = 0;
 | 
			
		||||
  } else {
 | 
			
		||||
      pos = 0;
 | 
			
		||||
    // We should never get here, but just in case...
 | 
			
		||||
    ESP_LOGW(TAG, "Max command length exceeded; ignoring");
 | 
			
		||||
    this->buffer_pos_ = 0;
 | 
			
		||||
  }
 | 
			
		||||
    if (pos >= 4) {
 | 
			
		||||
      if (memcmp(&buffer[pos - 4], &CMD_FRAME_FOOTER, sizeof(CMD_FRAME_FOOTER)) == 0) {
 | 
			
		||||
        this->set_cmd_active_(false);  // Set command state to inactive after responce.
 | 
			
		||||
        this->handle_ack_data_(buffer, pos);
 | 
			
		||||
        pos = 0;
 | 
			
		||||
      } else if ((buffer[pos - 2] == 0x0D && buffer[pos - 1] == 0x0A) &&
 | 
			
		||||
  if (this->buffer_pos_ < 4) {
 | 
			
		||||
    return;  // Not enough data to process yet
 | 
			
		||||
  }
 | 
			
		||||
  if (memcmp(&buffer[this->buffer_pos_ - 4], &CMD_FRAME_FOOTER, sizeof(CMD_FRAME_FOOTER)) == 0) {
 | 
			
		||||
    this->cmd_active_ = false;  // Set command state to inactive after response
 | 
			
		||||
    this->handle_ack_data_(buffer, this->buffer_pos_);
 | 
			
		||||
    this->buffer_pos_ = 0;
 | 
			
		||||
  } else if ((buffer[this->buffer_pos_ - 2] == 0x0D && buffer[this->buffer_pos_ - 1] == 0x0A) &&
 | 
			
		||||
             (this->get_mode_() == CMD_SYSTEM_MODE_SIMPLE)) {
 | 
			
		||||
        this->handle_simple_mode_(buffer, pos);
 | 
			
		||||
        pos = 0;
 | 
			
		||||
      } else if ((memcmp(&buffer[pos - 4], &ENERGY_FRAME_FOOTER, sizeof(ENERGY_FRAME_FOOTER)) == 0) &&
 | 
			
		||||
    this->handle_simple_mode_(buffer, this->buffer_pos_);
 | 
			
		||||
    this->buffer_pos_ = 0;
 | 
			
		||||
  } else if ((memcmp(&buffer[this->buffer_pos_ - 4], &ENERGY_FRAME_FOOTER, sizeof(ENERGY_FRAME_FOOTER)) == 0) &&
 | 
			
		||||
             (this->get_mode_() == CMD_SYSTEM_MODE_ENERGY)) {
 | 
			
		||||
        this->handle_energy_mode_(buffer, pos);
 | 
			
		||||
        pos = 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this->handle_energy_mode_(buffer, this->buffer_pos_);
 | 
			
		||||
    this->buffer_pos_ = 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -462,8 +460,9 @@ void LD2420Component::handle_energy_mode_(uint8_t *buffer, int len) {
 | 
			
		||||
 | 
			
		||||
  // Resonable refresh rate for home assistant database size health
 | 
			
		||||
  const int32_t current_millis = App.get_loop_component_start_time();
 | 
			
		||||
  if (current_millis - this->last_periodic_millis < REFRESH_RATE_MS)
 | 
			
		||||
  if (current_millis - this->last_periodic_millis < REFRESH_RATE_MS) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  this->last_periodic_millis = current_millis;
 | 
			
		||||
  for (auto &listener : this->listeners_) {
 | 
			
		||||
    listener->on_distance(this->get_distance_());
 | 
			
		||||
@@ -506,14 +505,16 @@ void LD2420Component::handle_simple_mode_(const uint8_t *inbuf, int len) {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  outbuf[index] = '\0';
 | 
			
		||||
  if (index > 1)
 | 
			
		||||
  if (index > 1) {
 | 
			
		||||
    this->set_distance_(strtol(outbuf, &endptr, 10));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (this->get_mode_() == CMD_SYSTEM_MODE_SIMPLE) {
 | 
			
		||||
    // Resonable refresh rate for home assistant database size health
 | 
			
		||||
    const int32_t current_millis = App.get_loop_component_start_time();
 | 
			
		||||
    if (current_millis - this->last_normal_periodic_millis < REFRESH_RATE_MS)
 | 
			
		||||
    if (current_millis - this->last_normal_periodic_millis < REFRESH_RATE_MS) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    this->last_normal_periodic_millis = current_millis;
 | 
			
		||||
    for (auto &listener : this->listeners_)
 | 
			
		||||
      listener->on_distance(this->get_distance_());
 | 
			
		||||
@@ -593,11 +594,12 @@ void LD2420Component::handle_ack_data_(uint8_t *buffer, int len) {
 | 
			
		||||
int LD2420Component::send_cmd_from_array(CmdFrameT frame) {
 | 
			
		||||
  uint32_t start_millis = millis();
 | 
			
		||||
  uint8_t error = 0;
 | 
			
		||||
  uint8_t ack_buffer[64];
 | 
			
		||||
  uint8_t cmd_buffer[64];
 | 
			
		||||
  uint8_t ack_buffer[MAX_LINE_LENGTH];
 | 
			
		||||
  uint8_t cmd_buffer[MAX_LINE_LENGTH];
 | 
			
		||||
  this->cmd_reply_.ack = false;
 | 
			
		||||
  if (frame.command != CMD_RESTART)
 | 
			
		||||
    this->set_cmd_active_(true);  // Restart does not reply, thus no ack state required.
 | 
			
		||||
  if (frame.command != CMD_RESTART) {
 | 
			
		||||
    this->cmd_active_ = true;
 | 
			
		||||
  }  // Restart does not reply, thus no ack state required
 | 
			
		||||
  uint8_t retry = 3;
 | 
			
		||||
  while (retry) {
 | 
			
		||||
    frame.length = 0;
 | 
			
		||||
@@ -619,9 +621,7 @@ int LD2420Component::send_cmd_from_array(CmdFrameT frame) {
 | 
			
		||||
 | 
			
		||||
    memcpy(cmd_buffer + frame.length, &frame.footer, sizeof(frame.footer));
 | 
			
		||||
    frame.length += sizeof(frame.footer);
 | 
			
		||||
    for (uint16_t index = 0; index < frame.length; index++) {
 | 
			
		||||
      this->write_byte(cmd_buffer[index]);
 | 
			
		||||
    }
 | 
			
		||||
    this->write_array(cmd_buffer, frame.length);
 | 
			
		||||
 | 
			
		||||
    error = 0;
 | 
			
		||||
    if (frame.command == CMD_RESTART) {
 | 
			
		||||
@@ -630,7 +630,7 @@ int LD2420Component::send_cmd_from_array(CmdFrameT frame) {
 | 
			
		||||
 | 
			
		||||
    while (!this->cmd_reply_.ack) {
 | 
			
		||||
      while (this->available()) {
 | 
			
		||||
        this->readline_(read(), ack_buffer, sizeof(ack_buffer));
 | 
			
		||||
        this->readline_(this->read(), ack_buffer, sizeof(ack_buffer));
 | 
			
		||||
      }
 | 
			
		||||
      delay_microseconds_safe(1450);
 | 
			
		||||
      // Wait on an Rx from the LD2420 for up to 3 1 second loops, otherwise it could trigger a WDT.
 | 
			
		||||
@@ -641,11 +641,13 @@ int LD2420Component::send_cmd_from_array(CmdFrameT frame) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (this->cmd_reply_.ack)
 | 
			
		||||
    if (this->cmd_reply_.ack) {
 | 
			
		||||
      retry = 0;
 | 
			
		||||
    if (this->cmd_reply_.error > 0)
 | 
			
		||||
    }
 | 
			
		||||
    if (this->cmd_reply_.error > 0) {
 | 
			
		||||
      this->handle_cmd_error(error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -764,8 +766,9 @@ void LD2420Component::set_system_mode(uint16_t mode) {
 | 
			
		||||
  cmd_frame.data_length += sizeof(unknown_parm);
 | 
			
		||||
  cmd_frame.footer = CMD_FRAME_FOOTER;
 | 
			
		||||
  ESP_LOGV(TAG, "Sending write system mode command: %2X", cmd_frame.command);
 | 
			
		||||
  if (this->send_cmd_from_array(cmd_frame) == 0)
 | 
			
		||||
  if (this->send_cmd_from_array(cmd_frame) == 0) {
 | 
			
		||||
    this->set_mode_(mode);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LD2420Component::get_firmware_version_() {
 | 
			
		||||
@@ -840,18 +843,24 @@ void LD2420Component::set_gate_threshold(uint8_t gate) {
 | 
			
		||||
 | 
			
		||||
#ifdef USE_NUMBER
 | 
			
		||||
void LD2420Component::init_gate_config_numbers() {
 | 
			
		||||
  if (this->gate_timeout_number_ != nullptr)
 | 
			
		||||
  if (this->gate_timeout_number_ != nullptr) {
 | 
			
		||||
    this->gate_timeout_number_->publish_state(static_cast<uint16_t>(this->current_config.timeout));
 | 
			
		||||
  if (this->gate_select_number_ != nullptr)
 | 
			
		||||
  }
 | 
			
		||||
  if (this->gate_select_number_ != nullptr) {
 | 
			
		||||
    this->gate_select_number_->publish_state(0);
 | 
			
		||||
  if (this->min_gate_distance_number_ != nullptr)
 | 
			
		||||
  }
 | 
			
		||||
  if (this->min_gate_distance_number_ != nullptr) {
 | 
			
		||||
    this->min_gate_distance_number_->publish_state(static_cast<uint16_t>(this->current_config.min_gate));
 | 
			
		||||
  if (this->max_gate_distance_number_ != nullptr)
 | 
			
		||||
  }
 | 
			
		||||
  if (this->max_gate_distance_number_ != nullptr) {
 | 
			
		||||
    this->max_gate_distance_number_->publish_state(static_cast<uint16_t>(this->current_config.max_gate));
 | 
			
		||||
  if (this->gate_move_sensitivity_factor_number_ != nullptr)
 | 
			
		||||
  }
 | 
			
		||||
  if (this->gate_move_sensitivity_factor_number_ != nullptr) {
 | 
			
		||||
    this->gate_move_sensitivity_factor_number_->publish_state(this->gate_move_sensitivity_factor);
 | 
			
		||||
  if (this->gate_still_sensitivity_factor_number_ != nullptr)
 | 
			
		||||
  }
 | 
			
		||||
  if (this->gate_still_sensitivity_factor_number_ != nullptr) {
 | 
			
		||||
    this->gate_still_sensitivity_factor_number_->publish_state(this->gate_still_sensitivity_factor);
 | 
			
		||||
  }
 | 
			
		||||
  for (uint8_t gate = 0; gate < TOTAL_GATES; gate++) {
 | 
			
		||||
    if (this->gate_still_threshold_numbers_[gate] != nullptr) {
 | 
			
		||||
      this->gate_still_threshold_numbers_[gate]->publish_state(
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,9 @@
 | 
			
		||||
namespace esphome {
 | 
			
		||||
namespace ld2420 {
 | 
			
		||||
 | 
			
		||||
static const uint8_t TOTAL_GATES = 16;
 | 
			
		||||
static const uint8_t CALIBRATE_SAMPLES = 64;
 | 
			
		||||
static const uint8_t MAX_LINE_LENGTH = 46;  // Max characters for serial buffer
 | 
			
		||||
static const uint8_t TOTAL_GATES = 16;
 | 
			
		||||
 | 
			
		||||
enum OpMode : uint8_t {
 | 
			
		||||
  OP_NORMAL_MODE = 1,
 | 
			
		||||
@@ -118,10 +119,10 @@ class LD2420Component : public Component, public uart::UARTDevice {
 | 
			
		||||
 | 
			
		||||
  float gate_move_sensitivity_factor{0.5};
 | 
			
		||||
  float gate_still_sensitivity_factor{0.5};
 | 
			
		||||
  int32_t last_periodic_millis = millis();
 | 
			
		||||
  int32_t report_periodic_millis = millis();
 | 
			
		||||
  int32_t monitor_periodic_millis = millis();
 | 
			
		||||
  int32_t last_normal_periodic_millis = millis();
 | 
			
		||||
  int32_t last_periodic_millis{0};
 | 
			
		||||
  int32_t report_periodic_millis{0};
 | 
			
		||||
  int32_t monitor_periodic_millis{0};
 | 
			
		||||
  int32_t last_normal_periodic_millis{0};
 | 
			
		||||
  uint16_t radar_data[TOTAL_GATES][CALIBRATE_SAMPLES];
 | 
			
		||||
  uint16_t gate_avg[TOTAL_GATES];
 | 
			
		||||
  uint16_t gate_peak[TOTAL_GATES];
 | 
			
		||||
@@ -161,8 +162,6 @@ class LD2420Component : public Component, public uart::UARTDevice {
 | 
			
		||||
  void set_presence_(bool presence) { this->presence_ = presence; };
 | 
			
		||||
  uint16_t get_distance_() { return this->distance_; };
 | 
			
		||||
  void set_distance_(uint16_t distance) { this->distance_ = distance; };
 | 
			
		||||
  bool get_cmd_active_() { return this->cmd_active_; };
 | 
			
		||||
  void set_cmd_active_(bool active) { this->cmd_active_ = active; };
 | 
			
		||||
  void handle_simple_mode_(const uint8_t *inbuf, int len);
 | 
			
		||||
  void handle_energy_mode_(uint8_t *buffer, int len);
 | 
			
		||||
  void handle_ack_data_(uint8_t *buffer, int len);
 | 
			
		||||
@@ -181,12 +180,11 @@ class LD2420Component : public Component, public uart::UARTDevice {
 | 
			
		||||
  std::vector<number::Number *> gate_move_threshold_numbers_ = std::vector<number::Number *>(16);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  uint32_t max_distance_gate_;
 | 
			
		||||
  uint32_t min_distance_gate_;
 | 
			
		||||
  uint16_t distance_{0};
 | 
			
		||||
  uint16_t system_mode_;
 | 
			
		||||
  uint16_t gate_energy_[TOTAL_GATES];
 | 
			
		||||
  uint16_t distance_{0};
 | 
			
		||||
  uint8_t config_checksum_{0};
 | 
			
		||||
  uint8_t buffer_pos_{0};  // where to resume processing/populating buffer
 | 
			
		||||
  uint8_t buffer_data_[MAX_LINE_LENGTH];
 | 
			
		||||
  char firmware_ver_[8]{"v0.0.0"};
 | 
			
		||||
  bool cmd_active_{false};
 | 
			
		||||
  bool presence_{false};
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
#include "esphome/core/helpers.h"
 | 
			
		||||
#include "esphome/core/log.h"
 | 
			
		||||
 | 
			
		||||
static const char *const TAG = "LD2420.number";
 | 
			
		||||
static const char *const TAG = "ld2420.number";
 | 
			
		||||
 | 
			
		||||
namespace esphome {
 | 
			
		||||
namespace ld2420 {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
namespace esphome {
 | 
			
		||||
namespace ld2420 {
 | 
			
		||||
 | 
			
		||||
static const char *const TAG = "LD2420.select";
 | 
			
		||||
static const char *const TAG = "ld2420.select";
 | 
			
		||||
 | 
			
		||||
void LD2420Select::control(const std::string &value) {
 | 
			
		||||
  this->publish_state(value);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,10 +5,10 @@
 | 
			
		||||
namespace esphome {
 | 
			
		||||
namespace ld2420 {
 | 
			
		||||
 | 
			
		||||
static const char *const TAG = "LD2420.sensor";
 | 
			
		||||
static const char *const TAG = "ld2420.sensor";
 | 
			
		||||
 | 
			
		||||
void LD2420Sensor::dump_config() {
 | 
			
		||||
  ESP_LOGCONFIG(TAG, "LD2420 Sensor:");
 | 
			
		||||
  ESP_LOGCONFIG(TAG, "Sensor:");
 | 
			
		||||
  LOG_SENSOR("  ", "Distance", this->distance_sensor_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,10 +5,10 @@
 | 
			
		||||
namespace esphome {
 | 
			
		||||
namespace ld2420 {
 | 
			
		||||
 | 
			
		||||
static const char *const TAG = "LD2420.text_sensor";
 | 
			
		||||
static const char *const TAG = "ld2420.text_sensor";
 | 
			
		||||
 | 
			
		||||
void LD2420TextSensor::dump_config() {
 | 
			
		||||
  ESP_LOGCONFIG(TAG, "LD2420 TextSensor:");
 | 
			
		||||
  ESP_LOGCONFIG(TAG, "Text Sensor:");
 | 
			
		||||
  LOG_TEXT_SENSOR("  ", "Firmware", this->fw_version_text_sensor_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user