mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 12:17:23 +00:00
223 lines
7.2 KiB
YAML
223 lines
7.2 KiB
YAML
esphome:
|
|
name: uart-mock-ld2450-test
|
|
|
|
host:
|
|
api:
|
|
batch_delay: 0ms # Disable batching to receive all state updates
|
|
logger:
|
|
level: VERBOSE
|
|
|
|
external_components:
|
|
- source:
|
|
type: local
|
|
path: EXTERNAL_COMPONENT_PATH
|
|
|
|
# Dummy uart entry to satisfy ld2450's DEPENDENCIES = ["uart"]
|
|
# The actual UART bus used is the uart_mock component below
|
|
uart:
|
|
baud_rate: 115200
|
|
port: /dev/null
|
|
|
|
uart_mock:
|
|
id: mock_uart
|
|
baud_rate: 256000
|
|
auto_start: false
|
|
responses:
|
|
# Catch-all response: match any command footer (04 03 02 01).
|
|
# Returns a generic ACK to unblock setup commands.
|
|
#
|
|
# Response layout:
|
|
# [0-3] FD FC FB FA = header
|
|
# [4-5] 04 00 = length 4
|
|
# [6] FF = cmd (handled as CMD_ENABLE_CONF)
|
|
# [7] 01 = status (ACK)
|
|
# [8-9] 00 00 = error = 0
|
|
# [10-13] 04 03 02 01 = footer
|
|
- expect_tx: [0x04, 0x03, 0x02, 0x01]
|
|
inject_rx:
|
|
[
|
|
0xFD, 0xFC, 0xFB, 0xFA,
|
|
0x04, 0x00,
|
|
0xFF, 0x01,
|
|
0x00, 0x00,
|
|
0x04, 0x03, 0x02, 0x01,
|
|
]
|
|
|
|
injections:
|
|
# Phase 1 (t=100ms): Valid LD2450 periodic data frame - happy path
|
|
# The buffer is clean at this point, so this frame should parse correctly.
|
|
#
|
|
# Target 1: X=-500mm, Y=1000mm, Speed=-50mm/s (approaching), Res=320mm
|
|
# X: magnitude=500 (0x01F4), negative → high=0x01, low=0xF4
|
|
# Y: magnitude=1000 (0x03E8), positive → high=0x83, low=0xE8
|
|
# Speed: raw=5, negative (approaching) → high=0x00, low=0x05, decoded=-50mm/s
|
|
# Resolution: 320 → low=0x40, high=0x01
|
|
# Distance: sqrt(500²+1000²) = sqrt(1250000) ≈ 1118mm
|
|
#
|
|
# Target 2: X=200mm, Y=500mm, Speed=0 (stationary), Res=100mm
|
|
# X: magnitude=200 (0x00C8), positive → high=0x80, low=0xC8
|
|
# Y: magnitude=500 (0x01F4), positive → high=0x81, low=0xF4
|
|
# Speed: 0 → 0x00, 0x00
|
|
# Resolution: 100 → low=0x64, high=0x00
|
|
# Distance: sqrt(200²+500²) = sqrt(290000) ≈ 538mm
|
|
#
|
|
# Target 3: No target (all zeros)
|
|
# Distance: 0 → sensors publish unknown/NaN
|
|
#
|
|
# Counts: target_count=2, moving_target_count=1, still_target_count=1
|
|
#
|
|
# Frame layout (30 bytes):
|
|
# [0-3] AA FF 03 00 = periodic data header
|
|
# [4-11] Target 1 (8 bytes): X_L X_H Y_L Y_H SPD_L SPD_H RES_L RES_H
|
|
# [12-19] Target 2 (8 bytes)
|
|
# [20-27] Target 3 (8 bytes)
|
|
# [28-29] 55 CC = periodic data footer
|
|
- delay: 100ms
|
|
inject_rx:
|
|
[
|
|
0xAA, 0xFF, 0x03, 0x00,
|
|
0xF4, 0x01, 0xE8, 0x83, 0x05, 0x00, 0x40, 0x01,
|
|
0xC8, 0x80, 0xF4, 0x81, 0x00, 0x00, 0x64, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x55, 0xCC,
|
|
]
|
|
|
|
# Phase 2 (t=300ms): Garbage bytes
|
|
# LD2450's readline_ does NOT reject bytes at position 0 (unlike LD2412),
|
|
# so these bytes accumulate in the buffer. buffer_pos_ goes from 0 to 7.
|
|
- delay: 200ms
|
|
inject_rx: [0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x11, 0x22]
|
|
|
|
# Phase 3 (t=400ms): Truncated frame (header + partial data, no footer)
|
|
# More bytes accumulating in the buffer without a footer match.
|
|
# After this, buffer_pos_ = 7 + 8 = 15.
|
|
- delay: 100ms
|
|
inject_rx: [0xAA, 0xFF, 0x03, 0x00, 0x01, 0x02, 0x03, 0x04]
|
|
|
|
# Phase 4 (t=600ms): Overflow - inject 75 bytes of 0xFF (MAX_LINE_LENGTH=45)
|
|
# Buffer has 15 bytes from phases 2+3.
|
|
# readline_() stores bytes while buffer_pos_ < 44. When buffer_pos_ == 44,
|
|
# the next byte triggers overflow: logs warning, resets buffer_pos_ to 0,
|
|
# and discards that byte.
|
|
#
|
|
# First overflow: 29 bytes fill positions 15-43 (buffer_pos_=44), byte 30
|
|
# triggers overflow (discarded). Total consumed: 30 bytes.
|
|
# Second overflow: 44 bytes fill positions 0-43 (buffer_pos_=44), byte 45
|
|
# triggers overflow (discarded). Total consumed: 30+45 = 75 bytes.
|
|
# After both overflows, buffer_pos_ = 0 (clean state for recovery frame).
|
|
- delay: 200ms
|
|
inject_rx:
|
|
[
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
]
|
|
|
|
# Phase 5 (t=700ms): Valid frame after overflow - recovery test
|
|
# Buffer was reset by overflow. This valid frame should parse correctly.
|
|
#
|
|
# Target 1: X=300mm, Y=400mm, Speed=30mm/s (moving away), Res=100mm
|
|
# X: magnitude=300 (0x012C), positive → high=0x81, low=0x2C
|
|
# Y: magnitude=400 (0x0190), positive → high=0x81, low=0x90
|
|
# Speed: raw=3, positive (moving away) → high=0x80, low=0x03, decoded=30mm/s
|
|
# Resolution: 100 → low=0x64, high=0x00
|
|
# Distance: sqrt(300²+400²) = 500mm
|
|
#
|
|
# Target 2 & 3: No target (all zeros)
|
|
# Counts: target_count=1, moving_target_count=1, still_target_count=0
|
|
- delay: 100ms
|
|
inject_rx:
|
|
[
|
|
0xAA, 0xFF, 0x03, 0x00,
|
|
0x2C, 0x81, 0x90, 0x81, 0x03, 0x80, 0x64, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x55, 0xCC,
|
|
]
|
|
|
|
ld2450:
|
|
id: ld2450_dev
|
|
uart_id: mock_uart
|
|
|
|
sensor:
|
|
- platform: ld2450
|
|
ld2450_id: ld2450_dev
|
|
target_count:
|
|
name: "Target Count"
|
|
filters: &sensor_filters
|
|
- timeout:
|
|
timeout: 50ms
|
|
value: last
|
|
- throttle_with_priority: 50ms
|
|
still_target_count:
|
|
name: "Still Target Count"
|
|
filters: *sensor_filters
|
|
moving_target_count:
|
|
name: "Moving Target Count"
|
|
filters: *sensor_filters
|
|
target_1:
|
|
x:
|
|
name: "Target 1 X"
|
|
filters: *sensor_filters
|
|
y:
|
|
name: "Target 1 Y"
|
|
filters: *sensor_filters
|
|
speed:
|
|
name: "Target 1 Speed"
|
|
filters: *sensor_filters
|
|
distance:
|
|
name: "Target 1 Distance"
|
|
filters: *sensor_filters
|
|
resolution:
|
|
name: "Target 1 Resolution"
|
|
filters: *sensor_filters
|
|
angle:
|
|
name: "Target 1 Angle"
|
|
filters: *sensor_filters
|
|
target_2:
|
|
x:
|
|
name: "Target 2 X"
|
|
filters: *sensor_filters
|
|
y:
|
|
name: "Target 2 Y"
|
|
filters: *sensor_filters
|
|
speed:
|
|
name: "Target 2 Speed"
|
|
filters: *sensor_filters
|
|
distance:
|
|
name: "Target 2 Distance"
|
|
filters: *sensor_filters
|
|
|
|
binary_sensor:
|
|
- platform: ld2450
|
|
ld2450_id: ld2450_dev
|
|
has_target:
|
|
name: "Has Target"
|
|
filters: &binary_sensor_filters
|
|
- settle: 50ms
|
|
has_moving_target:
|
|
name: "Has Moving Target"
|
|
filters: *binary_sensor_filters
|
|
has_still_target:
|
|
name: "Has Still Target"
|
|
filters: *binary_sensor_filters
|
|
|
|
text_sensor:
|
|
- platform: ld2450
|
|
ld2450_id: ld2450_dev
|
|
target_1:
|
|
direction:
|
|
name: "Target 1 Direction"
|
|
|
|
button:
|
|
- platform: template
|
|
name: "Start Scenario"
|
|
id: start_scenario_btn
|
|
on_press:
|
|
- lambda: 'id(mock_uart).start_scenario();'
|