diff --git a/esphome/components/ld2450/ld2450.cpp b/esphome/components/ld2450/ld2450.cpp index e6b4e7c719..21cf622f43 100644 --- a/esphome/components/ld2450/ld2450.cpp +++ b/esphome/components/ld2450/ld2450.cpp @@ -88,6 +88,9 @@ void LD2450Component::dump_config() { for (sensor::Sensor *s : this->move_resolution_sensors_) { LOG_SENSOR(" ", "NthTargetResolutionSensor", s); } + for (sensor::Sensor *s : this->zone_target_count_sensors_) { + LOG_SENSOR(" ", "NthZoneTargetCountSensor", s); + } #endif #ifdef USE_TEXT_SENSOR LOG_TEXT_SENSOR(" ", "VersionTextSensor", this->version_text_sensor_); @@ -132,6 +135,17 @@ void LD2450Component::loop() { } } +// Count targets in zone +uint8_t LD2450Component::count_targets_in_zone_(const Zone &zone) { + uint8_t count = 0; + for (auto &index : this->target_info_) { + if (index.x >= zone.x1 && index.x <= zone.x2 && index.y >= zone.y1 && index.y <= zone.y2) { + count++; + } + } + return count; +} + // Service reset_radar_zone void LD2450Component::on_reset_radar_zone_() { this->zone_type_ = 0; @@ -387,9 +401,25 @@ void LD2450Component::handle_periodic_data_(uint8_t *buffer, int len) { } } #endif + + this->target_info_[index].x = tx; + this->target_info_[index].y = ty; + } // End loop thru targets #ifdef USE_SENSOR + // Loop thru zones + for (index = 0; index < MAX_ZONES; index++) { + // Publish Target Count in Zones + sensor::Sensor *sztc = this->zone_target_count_sensors_[index]; + if (sztc != nullptr) { + val = this->count_targets_in_zone_(this->zone_config_[index]); + if (sztc->get_state() != val) { + sztc->publish_state(val); + } + } + } // End loop thru zones + still_target_count = target_count - moving_target_count; // Target Count if (this->target_count_sensor_ != nullptr) { @@ -711,6 +741,9 @@ void LD2450Component::set_move_distance_sensor(int target, sensor::Sensor *s) { void LD2450Component::set_move_resolution_sensor(int target, sensor::Sensor *s) { this->move_resolution_sensors_[target] = s; } +void LD2450Component::set_zone_target_count_sensor(int zone, sensor::Sensor *s) { + this->zone_target_count_sensors_[zone] = s; +} #endif #ifdef USE_TEXT_SENSOR void LD2450Component::set_direction_text_sensor(int target, text_sensor::TextSensor *s) { diff --git a/esphome/components/ld2450/ld2450.h b/esphome/components/ld2450/ld2450.h index 4c67c20380..f5b4a356e4 100644 --- a/esphome/components/ld2450/ld2450.h +++ b/esphome/components/ld2450/ld2450.h @@ -48,7 +48,13 @@ static const uint8_t DEFAULT_PRESENCE_TIMEOUT = 5; // Timeout to reset presense static const uint8_t MAX_TARGETS = 3; // Max 3 Targets in LD2450 static const uint8_t MAX_ZONES = 3; // Max 3 Zones in LD2450 -// Zone coordinate config +// Target coordinate struct +struct Target { + int16_t x; + int16_t y; +}; + +// Zone coordinate struct struct Zone { int16_t x1 = 0; int16_t y1 = 0; @@ -182,6 +188,7 @@ class LD2450Component : public Component, public uart::UARTDevice { void set_move_angle_sensor(int target, sensor::Sensor *s); void set_move_distance_sensor(int target, sensor::Sensor *s); void set_move_resolution_sensor(int target, sensor::Sensor *s); + void set_zone_target_count_sensor(int zone, sensor::Sensor *s); #endif protected: @@ -202,6 +209,7 @@ class LD2450Component : public Component, public uart::UARTDevice { void on_reset_radar_zone_(); void save_to_flash_(float value); float restore_from_flash_(); + Target target_info_[MAX_TARGETS]; Zone zone_config_[MAX_ZONES]; void on_set_radar_zone_(int zone_type, int zone1_x1, int zone1_y1, int zone1_x2, int zone1_y2, int zone2_x1, int zone2_y1, int zone2_x2, int zone2_y2, int zone3_x1, int zone3_y1, int zone3_x2, @@ -253,22 +261,24 @@ class LD2450Component : public Component, public uart::UARTDevice { std::string version_; std::string mac_; bool get_timeout_status_(int32_t check_millis); + uint8_t count_targets_in_zone_(const Zone &zone); #ifdef USE_TEXT_SENSOR std::vector direction_text_sensors_ = std::vector(3); #endif #ifdef USE_NUMBER - std::vector zone_x1_numbers_ = std::vector(3); - std::vector zone_y1_numbers_ = std::vector(3); - std::vector zone_x2_numbers_ = std::vector(3); - std::vector zone_y2_numbers_ = std::vector(3); + std::vector zone_x1_numbers_ = std::vector(MAX_ZONES); + std::vector zone_y1_numbers_ = std::vector(MAX_ZONES); + std::vector zone_x2_numbers_ = std::vector(MAX_ZONES); + std::vector zone_y2_numbers_ = std::vector(MAX_ZONES); #endif #ifdef USE_SENSOR - std::vector move_x_sensors_ = std::vector(3); - std::vector move_y_sensors_ = std::vector(3); - std::vector move_speed_sensors_ = std::vector(3); - std::vector move_angle_sensors_ = std::vector(3); - std::vector move_distance_sensors_ = std::vector(3); - std::vector move_resolution_sensors_ = std::vector(3); + std::vector move_x_sensors_ = std::vector(MAX_TARGETS); + std::vector move_y_sensors_ = std::vector(MAX_TARGETS); + std::vector move_speed_sensors_ = std::vector(MAX_TARGETS); + std::vector move_angle_sensors_ = std::vector(MAX_TARGETS); + std::vector move_distance_sensors_ = std::vector(MAX_TARGETS); + std::vector move_resolution_sensors_ = std::vector(MAX_TARGETS); + std::vector zone_target_count_sensors_ = std::vector(MAX_ZONES); #endif }; diff --git a/esphome/components/ld2450/sensor.py b/esphome/components/ld2450/sensor.py index 6ad77708d0..f0c51503ff 100644 --- a/esphome/components/ld2450/sensor.py +++ b/esphome/components/ld2450/sensor.py @@ -21,6 +21,7 @@ CONF_STILL_TARGET_COUNT = "still_target_count" CONF_MOVING_TARGET_COUNT = "moving_target_count" MAX_TARGETS = 3 +MAX_ZONES = 3 CONF_X = "x" CONF_Y = "y" @@ -78,6 +79,16 @@ CONFIG_SCHEMA = CONFIG_SCHEMA.extend( ) for n in range(MAX_TARGETS) }, + { + cv.Optional(f"zone_{n+1}"): cv.Schema( + { + cv.Optional(CONF_TARGET_COUNT): sensor.sensor_schema( + icon="mdi:map-marker-account", + ), + } + ) + for n in range(MAX_ZONES) + }, ) @@ -95,7 +106,6 @@ async def to_code(config): if moving_target_count_config := config.get(CONF_MOVING_TARGET_COUNT): sens = await sensor.new_sensor(moving_target_count_config) cg.add(ld2450_component.set_moving_target_count_sensor(sens)) - for n in range(MAX_TARGETS): if target_conf := config.get(f"target_{n+1}"): if x_config := target_conf.get(CONF_X): @@ -116,3 +126,7 @@ async def to_code(config): if resolution_config := target_conf.get(CONF_RESOLUTION): sens = await sensor.new_sensor(resolution_config) cg.add(ld2450_component.set_move_resolution_sensor(n, sens)) + for n in range(MAX_ZONES): + if zone_target_count_config := config.get(f"zone_{n+1}_target_count"): + sens = await sensor.new_sensor(zone_target_count_config) + cg.add(ld2450_component.set_zone_target_count_sensor(n, sens)) diff --git a/tests/test1.1.yaml b/tests/test1.1.yaml index 252713021c..b1523edeb9 100644 --- a/tests/test1.1.yaml +++ b/tests/test1.1.yaml @@ -300,6 +300,15 @@ sensor: name: Target-3 Distance resolution: name: Target-3 Resolution + zone_1: + target_count: + name: "Zone-1 Target Count" + zone_2: + target_count: + name: "Zone-2 Target Count" + zone_3: + target_count: + name: "Zone-3 Target Count" binary_sensor: - platform: ld2450