Files
esphome/tests/integration/fixtures/uart_mock_ld2420_simple.yaml

143 lines
4.5 KiB
YAML

esphome:
name: uart-mock-ld2420-simple-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 ld2420's DEPENDENCIES = ["uart"]
uart:
baud_rate: 115200
port: /dev/null
uart_mock:
id: mock_uart
baud_rate: 115200
auto_start: false
responses:
# Catch-all response only (no version-specific response).
# Without a version response, firmware_ver_ stays at default "v0.0.0".
# get_firmware_int("v0.0.0") = 0 < 154 → simple mode (CMD_SYSTEM_MODE_SIMPLE).
- 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 simple mode text frame - happy path
# "ON Range 0100\r\n" → presence=true, distance=100
# Simple mode frames end with \r\n (0x0D 0x0A), triggering handle_simple_mode_.
- delay: 100ms
inject_rx:
[
0x4F, 0x4E, 0x20, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x20,
0x30, 0x31, 0x30, 0x30,
0x0D, 0x0A,
]
# Phase 2 (t=300ms): Garbage bytes
# LD2420's readline_ stores all bytes regardless of header. buffer_pos_ = 7.
- delay: 200ms
inject_rx: [0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x11, 0x22]
# Phase 3 (t=500ms): Overflow - inject 50 bytes of 0xFF (MAX_LINE_LENGTH=50)
# buffer_pos_ starts at 7 (from Phase 2 garbage).
# Positions 7-48 fill (42 bytes), byte 43 triggers overflow (buffer_pos_=49).
# After overflow: buffer_pos_=0, remaining 7 bytes fill positions 0-6.
# Final buffer_pos_ = 7.
- 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,
]
# Phase 4 (t=1400ms): Recovery after overflow
# buffer_pos_ = 7 (from overflow remainder). These 15 bytes fill positions 7-21.
# At position 21 (0x0A), \r\n detected → handle_simple_mode_(buffer, 22).
# Parser skips 0xFF bytes at positions 0-6, finds "ON" at positions 7-8,
# parses digits "0050" → distance=50.
# Delay=900ms ensures >1000ms gap from Phase 1 for REFRESH_RATE_MS throttle.
- delay: 900ms
inject_rx:
[
0x4F, 0x4E, 0x20, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x20,
0x30, 0x30, 0x35, 0x30,
0x0D, 0x0A,
]
# Phase 5 (t=2500ms): 16-digit distance - tests PR #14458 bug #1
# "ON Range 0000000000000000\r\n" has 16 digit characters.
# handle_simple_mode_ outbuf is 16 bytes, can hold 15 digits (index 0-14).
#
# Pre-fix: At the 16th digit, index=15, (index < bufsize-1) is false.
# The digit branch doesn't increment pos. The else branch is skipped.
# pos stays at the 16th digit FOREVER → INFINITE LOOP.
# The binary hangs, no more state updates, test times out.
# Post-fix: pos always increments (moved outside digit branch).
# 16th digit skipped, loop continues to \r\n. distance=0.
- delay: 1100ms
inject_rx:
[
0x4F, 0x4E, 0x20, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x20,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x0D, 0x0A,
]
# Phase 6 (t=3700ms): Post-bug-trigger recovery
# If Phase 5 didn't hang, this frame should parse correctly.
# "ON Range 0025\r\n" → distance=25
# Delay=1200ms ensures >1000ms gap from Phase 5 for throttle.
- delay: 1200ms
inject_rx:
[
0x4F, 0x4E, 0x20, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x20,
0x30, 0x30, 0x32, 0x35,
0x0D, 0x0A,
]
button:
- platform: template
name: "Start Scenario"
on_press:
- lambda: 'id(mock_uart).start_scenario();'
ld2420:
id: ld2420_dev
uart_id: mock_uart
sensor:
- platform: ld2420
ld2420_id: ld2420_dev
moving_distance:
name: "Moving Distance"
filters:
- timeout:
timeout: 50ms
value: last
- throttle_with_priority: 50ms
binary_sensor:
- platform: ld2420
ld2420_id: ld2420_dev
has_target:
name: "Has Target"
filters:
- settle: 50ms