[remote_base] Generate the simple transmit actions with no C++ class (#20549)

This commit is contained in:
J. Nick Koston
2026-10-11 17:03:59 -10:00
committed by GitHub
parent d19bb7f4be
commit 08a55c97b7
36 changed files with 460 additions and 660 deletions
@@ -0,0 +1,13 @@
"""Helpers for the remote_transmitter component tests."""
import re
_PROTOCOL_CALL_BODY = re.compile(
r"auto apply_call = \S+->protocol_call<remote_base::\w+>\(\);\n(.*?)apply_call\.perform\(\);",
re.DOTALL,
)
def protocol_call_bodies(main_cpp: str) -> list[str]:
"""The statements of each generated transmit action, in config order."""
return _PROTOCOL_CALL_BODY.findall(main_cpp)
@@ -0,0 +1,41 @@
esphome:
name: test
esp8266:
board: esp01_1m
remote_transmitter:
pin: GPIO4
carrier_duty_percent: 50%
button:
- platform: template
name: Toto default repeat
on_press:
- remote_transmitter.transmit_toto:
command: 0xEC
rc_code_1: 0x0D
rc_code_2: 0x0D
- platform: template
name: Toto explicit repeat
on_press:
- remote_transmitter.transmit_toto:
command: 0xEC
rc_code_1: 0x0D
rc_code_2: 0x0D
repeat:
times: 2
wait_time: 20ms
- platform: template
name: NEC default wait
on_press:
- remote_transmitter.transmit_nec:
address: 0x4242
command: 0x8484
repeat: 4
- platform: template
name: NEC once
on_press:
- remote_transmitter.transmit_nec:
address: 0x4242
command: 0x8484
@@ -1,18 +1,23 @@
"""transmit_keeloq sets the suffix only when suffix bits are sent."""
"""transmit_keeloq sets the suffix only when the config names it."""
from collections.abc import Callable
from pathlib import Path
from tests.component_tests.remote_transmitter import protocol_call_bodies
def test_keeloq_suffix_is_set_only_with_suffix_bits(
def test_keeloq_suffix_is_set_only_when_configured(
generate_main: Callable[[str | Path], str],
component_config_path: Callable[[str], Path],
) -> None:
main_cpp = generate_main(component_config_path("keeloq_suffix.yaml"))
# The plain word gets the same setters as before the suffix existed.
assert "remote_base_keeloqaction_id->set_suffix" not in main_cpp
# A constant and a lambda width both set the suffix.
for action in ("remote_base_keeloqaction_id_2", "remote_base_keeloqaction_id_3"):
assert f"{action}->set_suffix([]() -> uint16_t" in main_cpp
assert f"{action}->set_suffix_bits([]() -> uint8_t" in main_cpp
bodies = protocol_call_bodies(main_cpp)
assert len(bodies) == 3
plain, constant, lambda_ = bodies
# The plain word fills only the HCS301 fields.
assert "data.suffix" not in plain
assert "apply_call.data.suffix = 0x2A;" in constant
assert "apply_call.data.suffix_bits = 6;" in constant
# A lambda is called inline.
assert "apply_call.data.suffix = static_cast<uint16_t>(0x2A);" in lambda_
assert "apply_call.data.suffix_bits = static_cast<uint8_t>(6);" in lambda_
@@ -0,0 +1,27 @@
"""repeat on a generated transmit action, and toto's default."""
from collections.abc import Callable
from pathlib import Path
from tests.component_tests.remote_transmitter import protocol_call_bodies
def test_transmit_repeat(
generate_main: Callable[[str | Path], str],
component_config_path: Callable[[str], Path],
) -> None:
main_cpp = generate_main(component_config_path("transmit_repeat.yaml"))
bodies = protocol_call_bodies(main_cpp)
assert len(bodies) == 4
toto_default, toto_explicit, nec_repeat, nec_once = bodies
# toto sends 3 times 36 ms apart unless the config says otherwise.
assert "apply_call.set_send_times(3);" in toto_default
assert "apply_call.set_send_wait(36000);" in toto_default
assert "apply_call.set_send_times(2);" in toto_explicit
assert "apply_call.set_send_wait(20000);" in toto_explicit
# A bare count gets the 25 ms default wait, in microseconds.
assert "apply_call.set_send_times(4);" in nec_repeat
assert "apply_call.set_send_wait(25000);" in nec_repeat
# Without repeat neither setter is emitted; the call sends once.
assert "set_send_times" not in nec_once
assert "set_send_wait" not in nec_once