esphome: name: ld2410b-counter friendly_name: "LD2410B Conveyor Counter" esp32: board: esp32dev framework: type: arduino # Подключение LD2410B по UART uart: tx_pin: GPIO17 rx_pin: GPIO16 baud_rate: 256000 parity: NONE stop_bits: 1 # GPIO OUT пин для быстрого детектирования движения binary_sensor: - platform: gpio pin: GPIO18 name: "LD2410B Motion GPIO" id: motion_gpio device_class: motion internal: true ld2410: sensor: # Дистанция до движущейся цели - platform: ld2410 moving_distance: name: "Moving Distance" id: moving_dist # Дистанция до неподвижной цели - platform: ld2410 still_distance: name: "Still Distance" id: still_dist # Энергия движения в зоне 0 (ближняя зона, 0.75-1.5м) - platform: ld2410 g0: move_energy: name: "Gate 0 Move Energy" id: g0_energy internal: true still_energy: name: "Gate 0 Still Energy" id: g0_still internal: true # Энергия движения в зоне 1 (1.5-2.25м) - platform: ld2410 g1: move_energy: name: "Gate 1 Move Energy" id: g1_energy internal: true # Счетчик прошедших товаров - platform: template name: "Items Count" id: items_count icon: "mdi:counter" unit_of_measurement: "items" accuracy_decimals: 0 state_class: total_increasing device_class: count # Дистанция срабатывания (для отладки) - platform: template name: "Trigger Distance" id: trigger_dist icon: "mdi:ruler" unit_of_measurement: "cm" accuracy_decimals: 0 update_interval: 0.5s # MQTT mqtt: broker: !secret mqtt_broker username: !secret mqtt_user password: !secret mqtt_pass topic_prefix: ld2410b/conveyor # Глобальные переменные для логики подсчета globals: - id: item_count_total type: int restore_value: true initial_value: "0" - id: item_state type: int restore_value: no initial_value: "0" - id: last_trigger_time type: unsigned long restore_value: no initial_value: "0" - id: energy_threshold type: float restore_value: no initial_value: "50.0" - id: distance_min_cm type: float restore_value: no initial_value: "75.0" - id: distance_max_cm type: float restore_value: no initial_value: "200.0" text_sensor: # Статус счетчика - platform: template name: "Counter Status" id: counter_status icon: "mdi:information" update_interval: 1s # Кнопки управления button: - platform: template name: "Reset Counter" id: reset_counter on_press: - lambda: |- id(item_count_total) = 0; id(items_count).publish_state(0); # Number для настройки порогов из Home Assistant / MQTT number: - platform: template name: "Energy Threshold" id: energy_threshold_ui min_value: 10 max_value: 100 step: 5 initial_value: 50 set_action: - lambda: id(energy_threshold) = x; - platform: template name: "Min Distance (cm)" id: dist_min_ui min_value: 50 max_value: 150 step: 5 initial_value: 75 set_action: - lambda: id(distance_min_cm) = x; - platform: template name: "Max Distance (cm)" id: dist_max_ui min_value: 100 max_value: 500 step: 10 initial_value: 200 set_action: - lambda: id(distance_max_cm) = x; # Основной цикл подсчета + статус interval: - interval: 50ms then: - lambda: |- // Получаем текущие значения float energy = id(g0_energy).state; float dist = id(moving_dist).state; // Проверка валидности дистанции bool valid_dist = (dist >= id(distance_min_cm)) && (dist <= id(distance_max_cm)); // Обновляем отладочный сенсор дистанции id(trigger_dist).publish_state(valid_dist ? dist : 0); // Конечный автомат: 0 = ожидание, 1 = объект в зоне, 2 = debounce после прохода unsigned long now = millis(); int current_state = id(item_state); // Объект вошел в зону (энергия выше порога + дистанция в пределах) if (current_state == 0 && energy > id(energy_threshold) && valid_dist) { id(item_state) = 1; id(last_trigger_time) = now; } // Объект ушел из зоны — инкремент счетчика if (current_state == 1 && energy < (id(energy_threshold) * 0.5)) { id(item_state) = 2; id(item_count_total)++; id(items_count).publish_state(id(item_count_total)); id(last_trigger_time) = now; } // Debounce: ждем 300мс после прохода перед новым детектом if (current_state == 2 && (now - id(last_trigger_time)) > 300) { id(item_state) = 0; } // Сброс stuck состояния (объект "завис" в зоне больше 5 сек) if (current_state == 1 && (now - id(last_trigger_time)) > 5000) { id(item_state) = 0; } - interval: 1s then: - lambda: |- std::string status = "State: " + std::to_string(id(item_state)) + " | E: " + std::to_string(id(g0_energy).state, 0) + " | D: " + std::to_string(id(moving_dist).state, 0) + " | Count: " + std::to_string(id(item_count_total)); id(counter_status).publish_state(status.c_str()); # Светодиод статуса (GPIO2 на ESP32 devkit) output: - platform: gpio pin: GPIO2 id: status_led light: - platform: binary id: led_status output: status_led internal: true logger: level: INFO