mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Merge branch 'duplicate_client_peername' into integration
This commit is contained in:
		| @@ -73,7 +73,6 @@ void APIConnection::start() { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   this->client_info_ = helper_->getpeername(); |   this->client_info_ = helper_->getpeername(); | ||||||
|   this->client_peername_ = this->client_info_; |  | ||||||
|   this->helper_->set_log_info(this->client_info_); |   this->helper_->set_log_info(this->client_info_); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1541,12 +1540,11 @@ bool APIConnection::try_send_log_message(int level, const char *tag, const char | |||||||
|  |  | ||||||
| HelloResponse APIConnection::hello(const HelloRequest &msg) { | HelloResponse APIConnection::hello(const HelloRequest &msg) { | ||||||
|   this->client_info_ = msg.client_info; |   this->client_info_ = msg.client_info; | ||||||
|   this->client_peername_ = this->helper_->getpeername(); |  | ||||||
|   this->helper_->set_log_info(this->get_client_combined_info()); |   this->helper_->set_log_info(this->get_client_combined_info()); | ||||||
|   this->client_api_version_major_ = msg.api_version_major; |   this->client_api_version_major_ = msg.api_version_major; | ||||||
|   this->client_api_version_minor_ = msg.api_version_minor; |   this->client_api_version_minor_ = msg.api_version_minor; | ||||||
|   ESP_LOGV(TAG, "Hello from client: '%s' | %s | API Version %" PRIu32 ".%" PRIu32, this->client_info_.c_str(), |   ESP_LOGV(TAG, "Hello from client: '%s' | %s | API Version %" PRIu32 ".%" PRIu32, this->client_info_.c_str(), | ||||||
|            this->client_peername_.c_str(), this->client_api_version_major_, this->client_api_version_minor_); |            this->helper_->getpeername().c_str(), this->client_api_version_major_, this->client_api_version_minor_); | ||||||
|  |  | ||||||
|   HelloResponse resp; |   HelloResponse resp; | ||||||
|   resp.api_version_major = 1; |   resp.api_version_major = 1; | ||||||
| @@ -1566,7 +1564,7 @@ ConnectResponse APIConnection::connect(const ConnectRequest &msg) { | |||||||
|   if (correct) { |   if (correct) { | ||||||
|     ESP_LOGD(TAG, "%s connected", this->get_client_combined_info().c_str()); |     ESP_LOGD(TAG, "%s connected", this->get_client_combined_info().c_str()); | ||||||
|     this->connection_state_ = ConnectionState::AUTHENTICATED; |     this->connection_state_ = ConnectionState::AUTHENTICATED; | ||||||
|     this->parent_->get_client_connected_trigger()->trigger(this->client_info_, this->client_peername_); |     this->parent_->get_client_connected_trigger()->trigger(this->client_info_, this->helper_->getpeername()); | ||||||
| #ifdef USE_HOMEASSISTANT_TIME | #ifdef USE_HOMEASSISTANT_TIME | ||||||
|     if (homeassistant::global_homeassistant_time != nullptr) { |     if (homeassistant::global_homeassistant_time != nullptr) { | ||||||
|       this->send_time_request(); |       this->send_time_request(); | ||||||
|   | |||||||
| @@ -275,11 +275,12 @@ class APIConnection : public APIServerConnection { | |||||||
|   bool send_buffer(ProtoWriteBuffer buffer, uint16_t message_type) override; |   bool send_buffer(ProtoWriteBuffer buffer, uint16_t message_type) override; | ||||||
|  |  | ||||||
|   std::string get_client_combined_info() const { |   std::string get_client_combined_info() const { | ||||||
|     if (this->client_info_ == this->client_peername_) { |     std::string peername = this->helper_->getpeername(); | ||||||
|  |     if (this->client_info_ == peername) { | ||||||
|       // Before Hello message, both are the same (just IP:port) |       // Before Hello message, both are the same (just IP:port) | ||||||
|       return this->client_info_; |       return this->client_info_; | ||||||
|     } |     } | ||||||
|     return this->client_info_ + " (" + this->client_peername_ + ")"; |     return this->client_info_ + " (" + peername + ")"; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Buffer allocator methods for batch processing |   // Buffer allocator methods for batch processing | ||||||
| @@ -454,7 +455,6 @@ class APIConnection : public APIServerConnection { | |||||||
|  |  | ||||||
|   // Strings (12 bytes each on 32-bit) |   // Strings (12 bytes each on 32-bit) | ||||||
|   std::string client_info_; |   std::string client_info_; | ||||||
|   std::string client_peername_; |  | ||||||
|  |  | ||||||
|   // 2-byte aligned types |   // 2-byte aligned types | ||||||
|   uint16_t client_api_version_major_{0}; |   uint16_t client_api_version_major_{0}; | ||||||
|   | |||||||
| @@ -184,7 +184,7 @@ void APIServer::loop() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Rare case: handle disconnection |     // Rare case: handle disconnection | ||||||
|     this->client_disconnected_trigger_->trigger(client->client_info_, client->client_peername_); |     this->client_disconnected_trigger_->trigger(client->client_info_, client->helper_->getpeername()); | ||||||
|     ESP_LOGV(TAG, "Remove connection %s", client->client_info_.c_str()); |     ESP_LOGV(TAG, "Remove connection %s", client->client_info_.c_str()); | ||||||
|  |  | ||||||
|     // Swap with the last element and pop (avoids expensive vector shifts) |     // Swap with the last element and pop (avoids expensive vector shifts) | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
|  |  | ||||||
| #include "esphome/core/application.h" | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
|  | #define CHECK_BIT(var, pos) (((var) >> (pos)) & 1) | ||||||
| #define highbyte(val) (uint8_t)((val) >> 8) | #define highbyte(val) (uint8_t)((val) >> 8) | ||||||
| #define lowbyte(val) (uint8_t)((val) &0xff) | #define lowbyte(val) (uint8_t)((val) &0xff) | ||||||
|  |  | ||||||
| @@ -17,8 +18,162 @@ namespace esphome { | |||||||
| namespace ld2410 { | namespace ld2410 { | ||||||
|  |  | ||||||
| static const char *const TAG = "ld2410"; | static const char *const TAG = "ld2410"; | ||||||
|  | static const char *const NO_MAC = "08:05:04:03:02:01"; | ||||||
|  | static const char *const UNKNOWN_MAC = "unknown"; | ||||||
|  | static const char *const VERSION_FMT = "%u.%02X.%02X%02X%02X%02X"; | ||||||
|  |  | ||||||
| LD2410Component::LD2410Component() {} | enum BaudRateStructure : uint8_t { | ||||||
|  |   BAUD_RATE_9600 = 1, | ||||||
|  |   BAUD_RATE_19200 = 2, | ||||||
|  |   BAUD_RATE_38400 = 3, | ||||||
|  |   BAUD_RATE_57600 = 4, | ||||||
|  |   BAUD_RATE_115200 = 5, | ||||||
|  |   BAUD_RATE_230400 = 6, | ||||||
|  |   BAUD_RATE_256000 = 7, | ||||||
|  |   BAUD_RATE_460800 = 8, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum DistanceResolutionStructure : uint8_t { | ||||||
|  |   DISTANCE_RESOLUTION_0_2 = 0x01, | ||||||
|  |   DISTANCE_RESOLUTION_0_75 = 0x00, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum LightFunctionStructure : uint8_t { | ||||||
|  |   LIGHT_FUNCTION_OFF = 0x00, | ||||||
|  |   LIGHT_FUNCTION_BELOW = 0x01, | ||||||
|  |   LIGHT_FUNCTION_ABOVE = 0x02, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum OutPinLevelStructure : uint8_t { | ||||||
|  |   OUT_PIN_LEVEL_LOW = 0x00, | ||||||
|  |   OUT_PIN_LEVEL_HIGH = 0x01, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum PeriodicDataStructure : uint8_t { | ||||||
|  |   DATA_TYPES = 6, | ||||||
|  |   TARGET_STATES = 8, | ||||||
|  |   MOVING_TARGET_LOW = 9, | ||||||
|  |   MOVING_TARGET_HIGH = 10, | ||||||
|  |   MOVING_ENERGY = 11, | ||||||
|  |   STILL_TARGET_LOW = 12, | ||||||
|  |   STILL_TARGET_HIGH = 13, | ||||||
|  |   STILL_ENERGY = 14, | ||||||
|  |   DETECT_DISTANCE_LOW = 15, | ||||||
|  |   DETECT_DISTANCE_HIGH = 16, | ||||||
|  |   MOVING_SENSOR_START = 19, | ||||||
|  |   STILL_SENSOR_START = 28, | ||||||
|  |   LIGHT_SENSOR = 37, | ||||||
|  |   OUT_PIN_SENSOR = 38, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum PeriodicDataValue : uint8_t { | ||||||
|  |   HEAD = 0xAA, | ||||||
|  |   END = 0x55, | ||||||
|  |   CHECK = 0x00, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum AckDataStructure : uint8_t { | ||||||
|  |   COMMAND = 6, | ||||||
|  |   COMMAND_STATUS = 7, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Memory-efficient lookup tables | ||||||
|  | struct StringToUint8 { | ||||||
|  |   const char *str; | ||||||
|  |   uint8_t value; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | struct Uint8ToString { | ||||||
|  |   uint8_t value; | ||||||
|  |   const char *str; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr StringToUint8 BAUD_RATES_BY_STR[] = { | ||||||
|  |     {"9600", BAUD_RATE_9600},     {"19200", BAUD_RATE_19200},   {"38400", BAUD_RATE_38400}, | ||||||
|  |     {"57600", BAUD_RATE_57600},   {"115200", BAUD_RATE_115200}, {"230400", BAUD_RATE_230400}, | ||||||
|  |     {"256000", BAUD_RATE_256000}, {"460800", BAUD_RATE_460800}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr StringToUint8 DISTANCE_RESOLUTIONS_BY_STR[] = { | ||||||
|  |     {"0.2m", DISTANCE_RESOLUTION_0_2}, | ||||||
|  |     {"0.75m", DISTANCE_RESOLUTION_0_75}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr Uint8ToString DISTANCE_RESOLUTIONS_BY_UINT[] = { | ||||||
|  |     {DISTANCE_RESOLUTION_0_2, "0.2m"}, | ||||||
|  |     {DISTANCE_RESOLUTION_0_75, "0.75m"}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr StringToUint8 LIGHT_FUNCTIONS_BY_STR[] = { | ||||||
|  |     {"off", LIGHT_FUNCTION_OFF}, | ||||||
|  |     {"below", LIGHT_FUNCTION_BELOW}, | ||||||
|  |     {"above", LIGHT_FUNCTION_ABOVE}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr Uint8ToString LIGHT_FUNCTIONS_BY_UINT[] = { | ||||||
|  |     {LIGHT_FUNCTION_OFF, "off"}, | ||||||
|  |     {LIGHT_FUNCTION_BELOW, "below"}, | ||||||
|  |     {LIGHT_FUNCTION_ABOVE, "above"}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr StringToUint8 OUT_PIN_LEVELS_BY_STR[] = { | ||||||
|  |     {"low", OUT_PIN_LEVEL_LOW}, | ||||||
|  |     {"high", OUT_PIN_LEVEL_HIGH}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr Uint8ToString OUT_PIN_LEVELS_BY_UINT[] = { | ||||||
|  |     {OUT_PIN_LEVEL_LOW, "low"}, | ||||||
|  |     {OUT_PIN_LEVEL_HIGH, "high"}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Helper functions 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) | ||||||
|  |       return entry.value; | ||||||
|  |   } | ||||||
|  |   return 0xFF;  // Not found | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template<size_t N> const char *find_str(const Uint8ToString (&arr)[N], uint8_t value) { | ||||||
|  |   for (const auto &entry : arr) { | ||||||
|  |     if (value == entry.value) | ||||||
|  |       return entry.str; | ||||||
|  |   } | ||||||
|  |   return "";  // Not found | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Commands | ||||||
|  | static const uint8_t CMD_ENABLE_CONF = 0xFF; | ||||||
|  | static const uint8_t CMD_DISABLE_CONF = 0xFE; | ||||||
|  | static const uint8_t CMD_ENABLE_ENG = 0x62; | ||||||
|  | static const uint8_t CMD_DISABLE_ENG = 0x63; | ||||||
|  | static const uint8_t CMD_MAXDIST_DURATION = 0x60; | ||||||
|  | static const uint8_t CMD_QUERY = 0x61; | ||||||
|  | static const uint8_t CMD_GATE_SENS = 0x64; | ||||||
|  | static const uint8_t CMD_VERSION = 0xA0; | ||||||
|  | static const uint8_t CMD_QUERY_DISTANCE_RESOLUTION = 0xAB; | ||||||
|  | static const uint8_t CMD_SET_DISTANCE_RESOLUTION = 0xAA; | ||||||
|  | static const uint8_t CMD_QUERY_LIGHT_CONTROL = 0xAE; | ||||||
|  | static const uint8_t CMD_SET_LIGHT_CONTROL = 0xAD; | ||||||
|  | static const uint8_t CMD_SET_BAUD_RATE = 0xA1; | ||||||
|  | static const uint8_t CMD_BT_PASSWORD = 0xA9; | ||||||
|  | static const uint8_t CMD_MAC = 0xA5; | ||||||
|  | static const uint8_t CMD_RESET = 0xA2; | ||||||
|  | static const uint8_t CMD_RESTART = 0xA3; | ||||||
|  | static const uint8_t CMD_BLUETOOTH = 0xA4; | ||||||
|  | // Commands values | ||||||
|  | static const uint8_t CMD_MAX_MOVE_VALUE = 0x00; | ||||||
|  | static const uint8_t CMD_MAX_STILL_VALUE = 0x01; | ||||||
|  | static const uint8_t CMD_DURATION_VALUE = 0x02; | ||||||
|  | // Command Header & Footer | ||||||
|  | static const uint8_t CMD_FRAME_HEADER[4] = {0xFD, 0xFC, 0xFB, 0xFA}; | ||||||
|  | static const uint8_t CMD_FRAME_END[4] = {0x04, 0x03, 0x02, 0x01}; | ||||||
|  | // Data Header & Footer | ||||||
|  | static const uint8_t DATA_FRAME_HEADER[4] = {0xF4, 0xF3, 0xF2, 0xF1}; | ||||||
|  | static const uint8_t DATA_FRAME_END[4] = {0xF8, 0xF7, 0xF6, 0xF5}; | ||||||
|  |  | ||||||
|  | static inline int two_byte_to_int(char firstbyte, char secondbyte) { return (int16_t) (secondbyte << 8) + firstbyte; } | ||||||
|  |  | ||||||
| void LD2410Component::dump_config() { | void LD2410Component::dump_config() { | ||||||
|   ESP_LOGCONFIG(TAG, "LD2410:"); |   ESP_LOGCONFIG(TAG, "LD2410:"); | ||||||
| @@ -78,7 +233,7 @@ void LD2410Component::dump_config() { | |||||||
|                 "  Throttle: %ums\n" |                 "  Throttle: %ums\n" | ||||||
|                 "  MAC address: %s\n" |                 "  MAC address: %s\n" | ||||||
|                 "  Firmware version: %s", |                 "  Firmware version: %s", | ||||||
|                 this->throttle_, const_cast<char *>(this->mac_.c_str()), const_cast<char *>(this->version_.c_str())); |                 this->throttle_, this->mac_ == NO_MAC ? UNKNOWN_MAC : this->mac_.c_str(), this->version_.c_str()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void LD2410Component::setup() { | void LD2410Component::setup() { | ||||||
| @@ -200,7 +355,7 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) { | |||||||
|   */ |   */ | ||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
|   if (this->moving_target_distance_sensor_ != nullptr) { |   if (this->moving_target_distance_sensor_ != nullptr) { | ||||||
|     int new_moving_target_distance = this->two_byte_to_int_(buffer[MOVING_TARGET_LOW], buffer[MOVING_TARGET_HIGH]); |     int new_moving_target_distance = ld2410::two_byte_to_int(buffer[MOVING_TARGET_LOW], buffer[MOVING_TARGET_HIGH]); | ||||||
|     if (this->moving_target_distance_sensor_->get_state() != new_moving_target_distance) |     if (this->moving_target_distance_sensor_->get_state() != new_moving_target_distance) | ||||||
|       this->moving_target_distance_sensor_->publish_state(new_moving_target_distance); |       this->moving_target_distance_sensor_->publish_state(new_moving_target_distance); | ||||||
|   } |   } | ||||||
| @@ -210,7 +365,7 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) { | |||||||
|       this->moving_target_energy_sensor_->publish_state(new_moving_target_energy); |       this->moving_target_energy_sensor_->publish_state(new_moving_target_energy); | ||||||
|   } |   } | ||||||
|   if (this->still_target_distance_sensor_ != nullptr) { |   if (this->still_target_distance_sensor_ != nullptr) { | ||||||
|     int new_still_target_distance = this->two_byte_to_int_(buffer[STILL_TARGET_LOW], buffer[STILL_TARGET_HIGH]); |     int new_still_target_distance = ld2410::two_byte_to_int(buffer[STILL_TARGET_LOW], buffer[STILL_TARGET_HIGH]); | ||||||
|     if (this->still_target_distance_sensor_->get_state() != new_still_target_distance) |     if (this->still_target_distance_sensor_->get_state() != new_still_target_distance) | ||||||
|       this->still_target_distance_sensor_->publish_state(new_still_target_distance); |       this->still_target_distance_sensor_->publish_state(new_still_target_distance); | ||||||
|   } |   } | ||||||
| @@ -220,7 +375,7 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) { | |||||||
|       this->still_target_energy_sensor_->publish_state(new_still_target_energy); |       this->still_target_energy_sensor_->publish_state(new_still_target_energy); | ||||||
|   } |   } | ||||||
|   if (this->detection_distance_sensor_ != nullptr) { |   if (this->detection_distance_sensor_ != nullptr) { | ||||||
|     int new_detect_distance = this->two_byte_to_int_(buffer[DETECT_DISTANCE_LOW], buffer[DETECT_DISTANCE_HIGH]); |     int new_detect_distance = ld2410::two_byte_to_int(buffer[DETECT_DISTANCE_LOW], buffer[DETECT_DISTANCE_HIGH]); | ||||||
|     if (this->detection_distance_sensor_->get_state() != new_detect_distance) |     if (this->detection_distance_sensor_->get_state() != new_detect_distance) | ||||||
|       this->detection_distance_sensor_->publish_state(new_detect_distance); |       this->detection_distance_sensor_->publish_state(new_detect_distance); | ||||||
|   } |   } | ||||||
| @@ -282,25 +437,6 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) { | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| const char VERSION_FMT[] = "%u.%02X.%02X%02X%02X%02X"; |  | ||||||
|  |  | ||||||
| std::string format_version(uint8_t *buffer) { |  | ||||||
|   std::string::size_type version_size = 256; |  | ||||||
|   std::string version; |  | ||||||
|   do { |  | ||||||
|     version.resize(version_size + 1); |  | ||||||
|     version_size = std::snprintf(&version[0], version.size(), VERSION_FMT, buffer[13], buffer[12], buffer[17], |  | ||||||
|                                  buffer[16], buffer[15], buffer[14]); |  | ||||||
|   } while (version_size + 1 > version.size()); |  | ||||||
|   version.resize(version_size); |  | ||||||
|   return version; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const char MAC_FMT[] = "%02X:%02X:%02X:%02X:%02X:%02X"; |  | ||||||
|  |  | ||||||
| const std::string UNKNOWN_MAC("unknown"); |  | ||||||
| const std::string NO_MAC("08:05:04:03:02:01"); |  | ||||||
|  |  | ||||||
| #ifdef USE_NUMBER | #ifdef USE_NUMBER | ||||||
| std::function<void(void)> set_number_value(number::Number *n, float value) { | std::function<void(void)> set_number_value(number::Number *n, float value) { | ||||||
|   float normalized_value = value * 1.0; |   float normalized_value = value * 1.0; | ||||||
| @@ -326,7 +462,7 @@ bool LD2410Component::handle_ack_data_(uint8_t *buffer, int len) { | |||||||
|     ESP_LOGE(TAG, "Invalid status"); |     ESP_LOGE(TAG, "Invalid status"); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|   if (this->two_byte_to_int_(buffer[8], buffer[9]) != 0x00) { |   if (ld2410::two_byte_to_int(buffer[8], buffer[9]) != 0x00) { | ||||||
|     ESP_LOGE(TAG, "Invalid command: %u, %u", buffer[8], buffer[9]); |     ESP_LOGE(TAG, "Invalid command: %u, %u", buffer[8], buffer[9]); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
| @@ -347,8 +483,8 @@ bool LD2410Component::handle_ack_data_(uint8_t *buffer, int len) { | |||||||
| #endif | #endif | ||||||
|       break; |       break; | ||||||
|     case lowbyte(CMD_VERSION): |     case lowbyte(CMD_VERSION): | ||||||
|       this->version_ = format_version(buffer); |       this->version_ = str_sprintf(VERSION_FMT, buffer[13], buffer[12], buffer[17], buffer[16], buffer[15], buffer[14]); | ||||||
|       ESP_LOGV(TAG, "Firmware version: %s", const_cast<char *>(this->version_.c_str())); |       ESP_LOGV(TAG, "Firmware version: %s", this->version_.c_str()); | ||||||
| #ifdef USE_TEXT_SENSOR | #ifdef USE_TEXT_SENSOR | ||||||
|       if (this->version_text_sensor_ != nullptr) { |       if (this->version_text_sensor_ != nullptr) { | ||||||
|         this->version_text_sensor_->publish_state(this->version_); |         this->version_text_sensor_->publish_state(this->version_); | ||||||
| @@ -357,8 +493,8 @@ bool LD2410Component::handle_ack_data_(uint8_t *buffer, int len) { | |||||||
|       break; |       break; | ||||||
|     case lowbyte(CMD_QUERY_DISTANCE_RESOLUTION): { |     case lowbyte(CMD_QUERY_DISTANCE_RESOLUTION): { | ||||||
|       std::string distance_resolution = |       std::string distance_resolution = | ||||||
|           DISTANCE_RESOLUTION_INT_TO_ENUM.at(this->two_byte_to_int_(buffer[10], buffer[11])); |           find_str(DISTANCE_RESOLUTIONS_BY_UINT, ld2410::two_byte_to_int(buffer[10], buffer[11])); | ||||||
|       ESP_LOGV(TAG, "Distance resolution: %s", const_cast<char *>(distance_resolution.c_str())); |       ESP_LOGV(TAG, "Distance resolution: %s", distance_resolution.c_str()); | ||||||
| #ifdef USE_SELECT | #ifdef USE_SELECT | ||||||
|       if (this->distance_resolution_select_ != nullptr && |       if (this->distance_resolution_select_ != nullptr && | ||||||
|           this->distance_resolution_select_->state != distance_resolution) { |           this->distance_resolution_select_->state != distance_resolution) { | ||||||
| @@ -367,9 +503,9 @@ bool LD2410Component::handle_ack_data_(uint8_t *buffer, int len) { | |||||||
| #endif | #endif | ||||||
|     } break; |     } break; | ||||||
|     case lowbyte(CMD_QUERY_LIGHT_CONTROL): { |     case lowbyte(CMD_QUERY_LIGHT_CONTROL): { | ||||||
|       this->light_function_ = LIGHT_FUNCTION_INT_TO_ENUM.at(buffer[10]); |       this->light_function_ = find_str(LIGHT_FUNCTIONS_BY_UINT, buffer[10]); | ||||||
|       this->light_threshold_ = buffer[11] * 1.0; |       this->light_threshold_ = buffer[11] * 1.0; | ||||||
|       this->out_pin_level_ = OUT_PIN_LEVEL_INT_TO_ENUM.at(buffer[12]); |       this->out_pin_level_ = find_str(OUT_PIN_LEVELS_BY_UINT, buffer[12]); | ||||||
|       ESP_LOGV(TAG, "Light function: %s", const_cast<char *>(this->light_function_.c_str())); |       ESP_LOGV(TAG, "Light function: %s", const_cast<char *>(this->light_function_.c_str())); | ||||||
|       ESP_LOGV(TAG, "Light threshold: %f", this->light_threshold_); |       ESP_LOGV(TAG, "Light threshold: %f", this->light_threshold_); | ||||||
|       ESP_LOGV(TAG, "Out pin level: %s", const_cast<char *>(this->out_pin_level_.c_str())); |       ESP_LOGV(TAG, "Out pin level: %s", const_cast<char *>(this->out_pin_level_.c_str())); | ||||||
| @@ -402,7 +538,7 @@ bool LD2410Component::handle_ack_data_(uint8_t *buffer, int len) { | |||||||
| #endif | #endif | ||||||
| #ifdef USE_SWITCH | #ifdef USE_SWITCH | ||||||
|       if (this->bluetooth_switch_ != nullptr) { |       if (this->bluetooth_switch_ != nullptr) { | ||||||
|         this->bluetooth_switch_->publish_state(this->mac_ != UNKNOWN_MAC); |         this->bluetooth_switch_->publish_state(this->mac_ != NO_MAC); | ||||||
|       } |       } | ||||||
| #endif | #endif | ||||||
|       break; |       break; | ||||||
| @@ -448,7 +584,7 @@ bool LD2410Component::handle_ack_data_(uint8_t *buffer, int len) { | |||||||
|       /* |       /* | ||||||
|         None Duration: 33~34th bytes |         None Duration: 33~34th bytes | ||||||
|       */ |       */ | ||||||
|       updates.push_back(set_number_value(this->timeout_number_, this->two_byte_to_int_(buffer[32], buffer[33]))); |       updates.push_back(set_number_value(this->timeout_number_, ld2410::two_byte_to_int(buffer[32], buffer[33]))); | ||||||
|       for (auto &update : updates) { |       for (auto &update : updates) { | ||||||
|         update(); |         update(); | ||||||
|       } |       } | ||||||
| @@ -505,14 +641,14 @@ void LD2410Component::set_bluetooth(bool enable) { | |||||||
|  |  | ||||||
| void LD2410Component::set_distance_resolution(const std::string &state) { | void LD2410Component::set_distance_resolution(const std::string &state) { | ||||||
|   this->set_config_mode_(true); |   this->set_config_mode_(true); | ||||||
|   uint8_t cmd_value[2] = {DISTANCE_RESOLUTION_ENUM_TO_INT.at(state), 0x00}; |   uint8_t cmd_value[2] = {find_uint8(DISTANCE_RESOLUTIONS_BY_STR, state), 0x00}; | ||||||
|   this->send_command_(CMD_SET_DISTANCE_RESOLUTION, cmd_value, 2); |   this->send_command_(CMD_SET_DISTANCE_RESOLUTION, cmd_value, 2); | ||||||
|   this->set_timeout(200, [this]() { this->restart_and_read_all_info(); }); |   this->set_timeout(200, [this]() { this->restart_and_read_all_info(); }); | ||||||
| } | } | ||||||
|  |  | ||||||
| void LD2410Component::set_baud_rate(const std::string &state) { | void LD2410Component::set_baud_rate(const std::string &state) { | ||||||
|   this->set_config_mode_(true); |   this->set_config_mode_(true); | ||||||
|   uint8_t cmd_value[2] = {BAUD_RATE_ENUM_TO_INT.at(state), 0x00}; |   uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00}; | ||||||
|   this->send_command_(CMD_SET_BAUD_RATE, cmd_value, 2); |   this->send_command_(CMD_SET_BAUD_RATE, cmd_value, 2); | ||||||
|   this->set_timeout(200, [this]() { this->restart_(); }); |   this->set_timeout(200, [this]() { this->restart_(); }); | ||||||
| } | } | ||||||
| @@ -646,9 +782,9 @@ void LD2410Component::set_light_out_control() { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   this->set_config_mode_(true); |   this->set_config_mode_(true); | ||||||
|   uint8_t light_function = LIGHT_FUNCTION_ENUM_TO_INT.at(this->light_function_); |   uint8_t light_function = find_uint8(LIGHT_FUNCTIONS_BY_STR, this->light_function_); | ||||||
|   uint8_t light_threshold = static_cast<uint8_t>(this->light_threshold_); |   uint8_t light_threshold = static_cast<uint8_t>(this->light_threshold_); | ||||||
|   uint8_t out_pin_level = OUT_PIN_LEVEL_ENUM_TO_INT.at(this->out_pin_level_); |   uint8_t out_pin_level = find_uint8(OUT_PIN_LEVELS_BY_STR, this->out_pin_level_); | ||||||
|   uint8_t value[4] = {light_function, light_threshold, out_pin_level, 0x00}; |   uint8_t value[4] = {light_function, light_threshold, out_pin_level, 0x00}; | ||||||
|   this->send_command_(CMD_SET_LIGHT_CONTROL, value, 4); |   this->send_command_(CMD_SET_LIGHT_CONTROL, value, 4); | ||||||
|   delay(50);  // NOLINT |   delay(50);  // NOLINT | ||||||
|   | |||||||
| @@ -26,114 +26,9 @@ | |||||||
| #include "esphome/core/automation.h" | #include "esphome/core/automation.h" | ||||||
| #include "esphome/core/helpers.h" | #include "esphome/core/helpers.h" | ||||||
|  |  | ||||||
| #include <map> |  | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace ld2410 { | namespace ld2410 { | ||||||
|  |  | ||||||
| #define CHECK_BIT(var, pos) (((var) >> (pos)) & 1) |  | ||||||
|  |  | ||||||
| // Commands |  | ||||||
| static const uint8_t CMD_ENABLE_CONF = 0x00FF; |  | ||||||
| static const uint8_t CMD_DISABLE_CONF = 0x00FE; |  | ||||||
| static const uint8_t CMD_ENABLE_ENG = 0x0062; |  | ||||||
| static const uint8_t CMD_DISABLE_ENG = 0x0063; |  | ||||||
| static const uint8_t CMD_MAXDIST_DURATION = 0x0060; |  | ||||||
| static const uint8_t CMD_QUERY = 0x0061; |  | ||||||
| static const uint8_t CMD_GATE_SENS = 0x0064; |  | ||||||
| static const uint8_t CMD_VERSION = 0x00A0; |  | ||||||
| static const uint8_t CMD_QUERY_DISTANCE_RESOLUTION = 0x00AB; |  | ||||||
| static const uint8_t CMD_SET_DISTANCE_RESOLUTION = 0x00AA; |  | ||||||
| static const uint8_t CMD_QUERY_LIGHT_CONTROL = 0x00AE; |  | ||||||
| static const uint8_t CMD_SET_LIGHT_CONTROL = 0x00AD; |  | ||||||
| static const uint8_t CMD_SET_BAUD_RATE = 0x00A1; |  | ||||||
| static const uint8_t CMD_BT_PASSWORD = 0x00A9; |  | ||||||
| static const uint8_t CMD_MAC = 0x00A5; |  | ||||||
| static const uint8_t CMD_RESET = 0x00A2; |  | ||||||
| static const uint8_t CMD_RESTART = 0x00A3; |  | ||||||
| static const uint8_t CMD_BLUETOOTH = 0x00A4; |  | ||||||
|  |  | ||||||
| enum BaudRateStructure : uint8_t { |  | ||||||
|   BAUD_RATE_9600 = 1, |  | ||||||
|   BAUD_RATE_19200 = 2, |  | ||||||
|   BAUD_RATE_38400 = 3, |  | ||||||
|   BAUD_RATE_57600 = 4, |  | ||||||
|   BAUD_RATE_115200 = 5, |  | ||||||
|   BAUD_RATE_230400 = 6, |  | ||||||
|   BAUD_RATE_256000 = 7, |  | ||||||
|   BAUD_RATE_460800 = 8 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const std::map<std::string, uint8_t> BAUD_RATE_ENUM_TO_INT{ |  | ||||||
|     {"9600", BAUD_RATE_9600},     {"19200", BAUD_RATE_19200},   {"38400", BAUD_RATE_38400}, |  | ||||||
|     {"57600", BAUD_RATE_57600},   {"115200", BAUD_RATE_115200}, {"230400", BAUD_RATE_230400}, |  | ||||||
|     {"256000", BAUD_RATE_256000}, {"460800", BAUD_RATE_460800}}; |  | ||||||
|  |  | ||||||
| enum DistanceResolutionStructure : uint8_t { DISTANCE_RESOLUTION_0_2 = 0x01, DISTANCE_RESOLUTION_0_75 = 0x00 }; |  | ||||||
|  |  | ||||||
| static const std::map<std::string, uint8_t> DISTANCE_RESOLUTION_ENUM_TO_INT{{"0.2m", DISTANCE_RESOLUTION_0_2}, |  | ||||||
|                                                                             {"0.75m", DISTANCE_RESOLUTION_0_75}}; |  | ||||||
| static const std::map<uint8_t, std::string> DISTANCE_RESOLUTION_INT_TO_ENUM{{DISTANCE_RESOLUTION_0_2, "0.2m"}, |  | ||||||
|                                                                             {DISTANCE_RESOLUTION_0_75, "0.75m"}}; |  | ||||||
|  |  | ||||||
| enum LightFunctionStructure : uint8_t { |  | ||||||
|   LIGHT_FUNCTION_OFF = 0x00, |  | ||||||
|   LIGHT_FUNCTION_BELOW = 0x01, |  | ||||||
|   LIGHT_FUNCTION_ABOVE = 0x02 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const std::map<std::string, uint8_t> LIGHT_FUNCTION_ENUM_TO_INT{ |  | ||||||
|     {"off", LIGHT_FUNCTION_OFF}, {"below", LIGHT_FUNCTION_BELOW}, {"above", LIGHT_FUNCTION_ABOVE}}; |  | ||||||
| static const std::map<uint8_t, std::string> LIGHT_FUNCTION_INT_TO_ENUM{ |  | ||||||
|     {LIGHT_FUNCTION_OFF, "off"}, {LIGHT_FUNCTION_BELOW, "below"}, {LIGHT_FUNCTION_ABOVE, "above"}}; |  | ||||||
|  |  | ||||||
| enum OutPinLevelStructure : uint8_t { OUT_PIN_LEVEL_LOW = 0x00, OUT_PIN_LEVEL_HIGH = 0x01 }; |  | ||||||
|  |  | ||||||
| static const std::map<std::string, uint8_t> OUT_PIN_LEVEL_ENUM_TO_INT{{"low", OUT_PIN_LEVEL_LOW}, |  | ||||||
|                                                                       {"high", OUT_PIN_LEVEL_HIGH}}; |  | ||||||
| static const std::map<uint8_t, std::string> OUT_PIN_LEVEL_INT_TO_ENUM{{OUT_PIN_LEVEL_LOW, "low"}, |  | ||||||
|                                                                       {OUT_PIN_LEVEL_HIGH, "high"}}; |  | ||||||
|  |  | ||||||
| // Commands values |  | ||||||
| static const uint8_t CMD_MAX_MOVE_VALUE = 0x0000; |  | ||||||
| static const uint8_t CMD_MAX_STILL_VALUE = 0x0001; |  | ||||||
| static const uint8_t CMD_DURATION_VALUE = 0x0002; |  | ||||||
| // Command Header & Footer |  | ||||||
| static const uint8_t CMD_FRAME_HEADER[4] = {0xFD, 0xFC, 0xFB, 0xFA}; |  | ||||||
| static const uint8_t CMD_FRAME_END[4] = {0x04, 0x03, 0x02, 0x01}; |  | ||||||
| // Data Header & Footer |  | ||||||
| static const uint8_t DATA_FRAME_HEADER[4] = {0xF4, 0xF3, 0xF2, 0xF1}; |  | ||||||
| static const uint8_t DATA_FRAME_END[4] = {0xF8, 0xF7, 0xF6, 0xF5}; |  | ||||||
| /* |  | ||||||
| Data Type: 6th byte |  | ||||||
| Target states: 9th byte |  | ||||||
|     Moving target distance: 10~11th bytes |  | ||||||
|     Moving target energy: 12th byte |  | ||||||
|     Still target distance: 13~14th bytes |  | ||||||
|     Still target energy: 15th byte |  | ||||||
|     Detect distance: 16~17th bytes |  | ||||||
| */ |  | ||||||
| enum PeriodicDataStructure : uint8_t { |  | ||||||
|   DATA_TYPES = 6, |  | ||||||
|   TARGET_STATES = 8, |  | ||||||
|   MOVING_TARGET_LOW = 9, |  | ||||||
|   MOVING_TARGET_HIGH = 10, |  | ||||||
|   MOVING_ENERGY = 11, |  | ||||||
|   STILL_TARGET_LOW = 12, |  | ||||||
|   STILL_TARGET_HIGH = 13, |  | ||||||
|   STILL_ENERGY = 14, |  | ||||||
|   DETECT_DISTANCE_LOW = 15, |  | ||||||
|   DETECT_DISTANCE_HIGH = 16, |  | ||||||
|   MOVING_SENSOR_START = 19, |  | ||||||
|   STILL_SENSOR_START = 28, |  | ||||||
|   LIGHT_SENSOR = 37, |  | ||||||
|   OUT_PIN_SENSOR = 38, |  | ||||||
| }; |  | ||||||
| enum PeriodicDataValue : uint8_t { HEAD = 0xAA, END = 0x55, CHECK = 0x00 }; |  | ||||||
|  |  | ||||||
| enum AckDataStructure : uint8_t { COMMAND = 6, COMMAND_STATUS = 7 }; |  | ||||||
|  |  | ||||||
| //  char cmd[2] = {enable ? 0xFF : 0xFE, 0x00}; |  | ||||||
| class LD2410Component : public Component, public uart::UARTDevice { | class LD2410Component : public Component, public uart::UARTDevice { | ||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
|   SUB_SENSOR(moving_target_distance) |   SUB_SENSOR(moving_target_distance) | ||||||
| @@ -176,7 +71,6 @@ class LD2410Component : public Component, public uart::UARTDevice { | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   LD2410Component(); |  | ||||||
|   void setup() override; |   void setup() override; | ||||||
|   void dump_config() override; |   void dump_config() override; | ||||||
|   void loop() override; |   void loop() override; | ||||||
| @@ -202,7 +96,6 @@ class LD2410Component : public Component, public uart::UARTDevice { | |||||||
|   void factory_reset(); |   void factory_reset(); | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   int two_byte_to_int_(char firstbyte, char secondbyte) { return (int16_t) (secondbyte << 8) + firstbyte; } |  | ||||||
|   void send_command_(uint8_t command_str, const uint8_t *command_value, int command_value_len); |   void send_command_(uint8_t command_str, const uint8_t *command_value, int command_value_len); | ||||||
|   void set_config_mode_(bool enable); |   void set_config_mode_(bool enable); | ||||||
|   void handle_periodic_data_(uint8_t *buffer, int len); |   void handle_periodic_data_(uint8_t *buffer, int len); | ||||||
| @@ -215,14 +108,14 @@ class LD2410Component : public Component, public uart::UARTDevice { | |||||||
|   void get_light_control_(); |   void get_light_control_(); | ||||||
|   void restart_(); |   void restart_(); | ||||||
|  |  | ||||||
|   int32_t last_periodic_millis_ = millis(); |   int32_t last_periodic_millis_ = 0; | ||||||
|   int32_t last_engineering_mode_change_millis_ = millis(); |   int32_t last_engineering_mode_change_millis_ = 0; | ||||||
|   uint16_t throttle_; |   uint16_t throttle_; | ||||||
|  |   float light_threshold_ = -1; | ||||||
|   std::string version_; |   std::string version_; | ||||||
|   std::string mac_; |   std::string mac_; | ||||||
|   std::string out_pin_level_; |   std::string out_pin_level_; | ||||||
|   std::string light_function_; |   std::string light_function_; | ||||||
|   float light_threshold_ = -1; |  | ||||||
| #ifdef USE_NUMBER | #ifdef USE_NUMBER | ||||||
|   std::vector<number::Number *> gate_still_threshold_numbers_ = std::vector<number::Number *>(9); |   std::vector<number::Number *> gate_still_threshold_numbers_ = std::vector<number::Number *>(9); | ||||||
|   std::vector<number::Number *> gate_move_threshold_numbers_ = std::vector<number::Number *>(9); |   std::vector<number::Number *> gate_move_threshold_numbers_ = std::vector<number::Number *>(9); | ||||||
|   | |||||||
| @@ -21,20 +21,105 @@ static const char *const NO_MAC = "08:05:04:03:02:01"; | |||||||
| static const char *const UNKNOWN_MAC = "unknown"; | static const char *const UNKNOWN_MAC = "unknown"; | ||||||
| static const char *const VERSION_FMT = "%u.%02X.%02X%02X%02X%02X"; | static const char *const VERSION_FMT = "%u.%02X.%02X%02X%02X%02X"; | ||||||
|  |  | ||||||
|  | enum BaudRateStructure : uint8_t { | ||||||
|  |   BAUD_RATE_9600 = 1, | ||||||
|  |   BAUD_RATE_19200 = 2, | ||||||
|  |   BAUD_RATE_38400 = 3, | ||||||
|  |   BAUD_RATE_57600 = 4, | ||||||
|  |   BAUD_RATE_115200 = 5, | ||||||
|  |   BAUD_RATE_230400 = 6, | ||||||
|  |   BAUD_RATE_256000 = 7, | ||||||
|  |   BAUD_RATE_460800 = 8 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Zone type struct | ||||||
|  | enum ZoneTypeStructure : uint8_t { | ||||||
|  |   ZONE_DISABLED = 0, | ||||||
|  |   ZONE_DETECTION = 1, | ||||||
|  |   ZONE_FILTER = 2, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum PeriodicDataStructure : uint8_t { | ||||||
|  |   TARGET_X = 4, | ||||||
|  |   TARGET_Y = 6, | ||||||
|  |   TARGET_SPEED = 8, | ||||||
|  |   TARGET_RESOLUTION = 10, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum PeriodicDataValue : uint8_t { | ||||||
|  |   HEAD = 0xAA, | ||||||
|  |   END = 0x55, | ||||||
|  |   CHECK = 0x00, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum AckDataStructure : uint8_t { | ||||||
|  |   COMMAND = 6, | ||||||
|  |   COMMAND_STATUS = 7, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Memory-efficient lookup tables | ||||||
|  | struct StringToUint8 { | ||||||
|  |   const char *str; | ||||||
|  |   uint8_t value; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | struct Uint8ToString { | ||||||
|  |   uint8_t value; | ||||||
|  |   const char *str; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr StringToUint8 BAUD_RATES_BY_STR[] = { | ||||||
|  |     {"9600", BAUD_RATE_9600},     {"19200", BAUD_RATE_19200},   {"38400", BAUD_RATE_38400}, | ||||||
|  |     {"57600", BAUD_RATE_57600},   {"115200", BAUD_RATE_115200}, {"230400", BAUD_RATE_230400}, | ||||||
|  |     {"256000", BAUD_RATE_256000}, {"460800", BAUD_RATE_460800}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr Uint8ToString ZONE_TYPE_BY_UINT[] = { | ||||||
|  |     {ZONE_DISABLED, "Disabled"}, | ||||||
|  |     {ZONE_DETECTION, "Detection"}, | ||||||
|  |     {ZONE_FILTER, "Filter"}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr StringToUint8 ZONE_TYPE_BY_STR[] = { | ||||||
|  |     {"Disabled", ZONE_DISABLED}, | ||||||
|  |     {"Detection", ZONE_DETECTION}, | ||||||
|  |     {"Filter", ZONE_FILTER}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Helper functions 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) | ||||||
|  |       return entry.value; | ||||||
|  |   } | ||||||
|  |   return 0xFF;  // Not found | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template<size_t N> const char *find_str(const Uint8ToString (&arr)[N], uint8_t value) { | ||||||
|  |   for (const auto &entry : arr) { | ||||||
|  |     if (value == entry.value) | ||||||
|  |       return entry.str; | ||||||
|  |   } | ||||||
|  |   return "";  // Not found | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // LD2450 serial command header & footer | ||||||
|  | static const uint8_t CMD_FRAME_HEADER[4] = {0xFD, 0xFC, 0xFB, 0xFA}; | ||||||
|  | static const uint8_t CMD_FRAME_END[4] = {0x04, 0x03, 0x02, 0x01}; | ||||||
| // LD2450 UART Serial Commands | // LD2450 UART Serial Commands | ||||||
| static const uint8_t CMD_ENABLE_CONF = 0x00FF; | static const uint8_t CMD_ENABLE_CONF = 0xFF; | ||||||
| static const uint8_t CMD_DISABLE_CONF = 0x00FE; | static const uint8_t CMD_DISABLE_CONF = 0xFE; | ||||||
| static const uint8_t CMD_VERSION = 0x00A0; | static const uint8_t CMD_VERSION = 0xA0; | ||||||
| static const uint8_t CMD_MAC = 0x00A5; | static const uint8_t CMD_MAC = 0xA5; | ||||||
| static const uint8_t CMD_RESET = 0x00A2; | static const uint8_t CMD_RESET = 0xA2; | ||||||
| static const uint8_t CMD_RESTART = 0x00A3; | static const uint8_t CMD_RESTART = 0xA3; | ||||||
| static const uint8_t CMD_BLUETOOTH = 0x00A4; | static const uint8_t CMD_BLUETOOTH = 0xA4; | ||||||
| static const uint8_t CMD_SINGLE_TARGET_MODE = 0x0080; | static const uint8_t CMD_SINGLE_TARGET_MODE = 0x80; | ||||||
| static const uint8_t CMD_MULTI_TARGET_MODE = 0x0090; | static const uint8_t CMD_MULTI_TARGET_MODE = 0x90; | ||||||
| static const uint8_t CMD_QUERY_TARGET_MODE = 0x0091; | static const uint8_t CMD_QUERY_TARGET_MODE = 0x91; | ||||||
| static const uint8_t CMD_SET_BAUD_RATE = 0x00A1; | static const uint8_t CMD_SET_BAUD_RATE = 0xA1; | ||||||
| static const uint8_t CMD_QUERY_ZONE = 0x00C1; | static const uint8_t CMD_QUERY_ZONE = 0xC1; | ||||||
| static const uint8_t CMD_SET_ZONE = 0x00C2; | static const uint8_t CMD_SET_ZONE = 0xC2; | ||||||
|  |  | ||||||
| static inline uint16_t convert_seconds_to_ms(uint16_t value) { return value * 1000; }; | static inline uint16_t convert_seconds_to_ms(uint16_t value) { return value * 1000; }; | ||||||
|  |  | ||||||
| @@ -720,7 +805,7 @@ void LD2450Component::set_bluetooth(bool enable) { | |||||||
| // Set Baud rate | // Set Baud rate | ||||||
| void LD2450Component::set_baud_rate(const std::string &state) { | void LD2450Component::set_baud_rate(const std::string &state) { | ||||||
|   this->set_config_mode_(true); |   this->set_config_mode_(true); | ||||||
|   uint8_t cmd_value[2] = {BAUD_RATE_ENUM_TO_INT.at(state), 0x00}; |   uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00}; | ||||||
|   this->send_command_(CMD_SET_BAUD_RATE, cmd_value, 2); |   this->send_command_(CMD_SET_BAUD_RATE, cmd_value, 2); | ||||||
|   this->set_timeout(200, [this]() { this->restart_(); }); |   this->set_timeout(200, [this]() { this->restart_(); }); | ||||||
| } | } | ||||||
| @@ -728,7 +813,7 @@ void LD2450Component::set_baud_rate(const std::string &state) { | |||||||
| // Set Zone Type - one of: Disabled, Detection, Filter | // Set Zone Type - one of: Disabled, Detection, Filter | ||||||
| void LD2450Component::set_zone_type(const std::string &state) { | void LD2450Component::set_zone_type(const std::string &state) { | ||||||
|   ESP_LOGV(TAG, "Set zone type: %s", state.c_str()); |   ESP_LOGV(TAG, "Set zone type: %s", state.c_str()); | ||||||
|   uint8_t zone_type = ZONE_TYPE_ENUM_TO_INT.at(state); |   uint8_t zone_type = find_uint8(ZONE_TYPE_BY_STR, state); | ||||||
|   this->zone_type_ = zone_type; |   this->zone_type_ = zone_type; | ||||||
|   this->send_set_zone_command_(); |   this->send_set_zone_command_(); | ||||||
| } | } | ||||||
| @@ -736,7 +821,7 @@ void LD2450Component::set_zone_type(const std::string &state) { | |||||||
| // Publish Zone Type to Select component | // Publish Zone Type to Select component | ||||||
| void LD2450Component::publish_zone_type() { | void LD2450Component::publish_zone_type() { | ||||||
| #ifdef USE_SELECT | #ifdef USE_SELECT | ||||||
|   std::string zone_type = ZONE_TYPE_INT_TO_ENUM.at(static_cast<ZoneTypeStructure>(this->zone_type_)); |   std::string zone_type = find_str(ZONE_TYPE_BY_UINT, this->zone_type_); | ||||||
|   if (this->zone_type_select_ != nullptr) { |   if (this->zone_type_select_ != nullptr) { | ||||||
|     this->zone_type_select_->publish_state(zone_type); |     this->zone_type_select_->publish_state(zone_type); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <iomanip> |  | ||||||
| #include <map> |  | ||||||
| #include "esphome/components/uart/uart.h" | #include "esphome/components/uart/uart.h" | ||||||
| #include "esphome/core/component.h" | #include "esphome/core/component.h" | ||||||
| #include "esphome/core/defines.h" | #include "esphome/core/defines.h" | ||||||
| @@ -66,49 +64,6 @@ struct ZoneOfNumbers { | |||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| enum BaudRateStructure : uint8_t { |  | ||||||
|   BAUD_RATE_9600 = 1, |  | ||||||
|   BAUD_RATE_19200 = 2, |  | ||||||
|   BAUD_RATE_38400 = 3, |  | ||||||
|   BAUD_RATE_57600 = 4, |  | ||||||
|   BAUD_RATE_115200 = 5, |  | ||||||
|   BAUD_RATE_230400 = 6, |  | ||||||
|   BAUD_RATE_256000 = 7, |  | ||||||
|   BAUD_RATE_460800 = 8 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| // Convert baud rate enum to int |  | ||||||
| static const std::map<std::string, uint8_t> BAUD_RATE_ENUM_TO_INT{ |  | ||||||
|     {"9600", BAUD_RATE_9600},     {"19200", BAUD_RATE_19200},   {"38400", BAUD_RATE_38400}, |  | ||||||
|     {"57600", BAUD_RATE_57600},   {"115200", BAUD_RATE_115200}, {"230400", BAUD_RATE_230400}, |  | ||||||
|     {"256000", BAUD_RATE_256000}, {"460800", BAUD_RATE_460800}}; |  | ||||||
|  |  | ||||||
| // Zone type struct |  | ||||||
| enum ZoneTypeStructure : uint8_t { ZONE_DISABLED = 0, ZONE_DETECTION = 1, ZONE_FILTER = 2 }; |  | ||||||
|  |  | ||||||
| // Convert zone type int to enum |  | ||||||
| static const std::map<ZoneTypeStructure, std::string> ZONE_TYPE_INT_TO_ENUM{ |  | ||||||
|     {ZONE_DISABLED, "Disabled"}, {ZONE_DETECTION, "Detection"}, {ZONE_FILTER, "Filter"}}; |  | ||||||
|  |  | ||||||
| // Convert zone type enum to int |  | ||||||
| static const std::map<std::string, uint8_t> ZONE_TYPE_ENUM_TO_INT{ |  | ||||||
|     {"Disabled", ZONE_DISABLED}, {"Detection", ZONE_DETECTION}, {"Filter", ZONE_FILTER}}; |  | ||||||
|  |  | ||||||
| // LD2450 serial command header & footer |  | ||||||
| static const uint8_t CMD_FRAME_HEADER[4] = {0xFD, 0xFC, 0xFB, 0xFA}; |  | ||||||
| static const uint8_t CMD_FRAME_END[4] = {0x04, 0x03, 0x02, 0x01}; |  | ||||||
|  |  | ||||||
| enum PeriodicDataStructure : uint8_t { |  | ||||||
|   TARGET_X = 4, |  | ||||||
|   TARGET_Y = 6, |  | ||||||
|   TARGET_SPEED = 8, |  | ||||||
|   TARGET_RESOLUTION = 10, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum PeriodicDataValue : uint8_t { HEAD = 0xAA, END = 0x55, CHECK = 0x00 }; |  | ||||||
|  |  | ||||||
| enum AckDataStructure : uint8_t { COMMAND = 6, COMMAND_STATUS = 7 }; |  | ||||||
|  |  | ||||||
| class LD2450Component : public Component, public uart::UARTDevice { | class LD2450Component : public Component, public uart::UARTDevice { | ||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
|   SUB_SENSOR(target_count) |   SUB_SENSOR(target_count) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user