mirror of
https://github.com/esphome/esphome.git
synced 2026-11-15 01:25:57 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c6ad8aaf0 | ||
|
|
456f1681d8 | ||
|
|
65ee248a13 | ||
|
|
504514eeaa |
No files matched your search
@@ -189,8 +189,7 @@ def register_start_scan_action(name: str, tracker_class: MockObjClass) -> None:
|
||||
if (continuous := config.get(CONF_CONTINUOUS)) is None:
|
||||
mode = tracker.configured_continuous()
|
||||
elif cg.is_template(continuous):
|
||||
lambda_ = await cg.process_lambda(continuous, args, return_type=cg.bool_)
|
||||
mode = automation.immediate_lambda_call(lambda_)
|
||||
mode = await automation.call_user_lambda(continuous, args, cg.bool_)
|
||||
else:
|
||||
mode = continuous
|
||||
text = str(cg.statement(ble_device_base_ns.start_scan(tracker, mode)))
|
||||
|
||||
@@ -64,7 +64,7 @@ from esphome.core import (
|
||||
coroutine,
|
||||
coroutine_with_priority,
|
||||
)
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.cpp_generator import MockObj, StaticCastExpression
|
||||
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
||||
from esphome.types import ConfigType, SafeExpType, TemplateArgsType
|
||||
from esphome.util import Registry, SimpleRegistry
|
||||
@@ -472,14 +472,13 @@ async def _transmit_value(
|
||||
type_: SafeExpType,
|
||||
const_fn: Callable[[Any], Any] = cg.safe_exp,
|
||||
) -> str:
|
||||
"""Argument text for one templatable transmit value.
|
||||
|
||||
A lambda keeps the trigger's own argument types and is always called, so its body may
|
||||
modify its by-value arguments.
|
||||
"""
|
||||
"""Argument text for one templatable transmit value."""
|
||||
if isinstance(value, Lambda):
|
||||
lamb = await cg.process_lambda(value, args, return_type=type_)
|
||||
return str(automation.immediate_lambda_call(lamb))
|
||||
expr = await automation.call_user_lambda(value, args, type_)
|
||||
if isinstance(expr, cg.RawExpression):
|
||||
# Used as an operand (.transmit, [0]): the cast binds as a whole and converts like the lambda's return
|
||||
expr = StaticCastExpression(type_, expr)
|
||||
return str(expr)
|
||||
return str(const_fn(value))
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from esphome.components.const import CONF_ON_STOP
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_MODE, CONF_PARAMETERS, CONF_RESTART
|
||||
from esphome.core import CORE, EsphomeError
|
||||
from esphome.cpp_generator import AssignmentExpression, call_lambda
|
||||
from esphome.types import ConfigType
|
||||
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
@@ -242,9 +243,13 @@ async def script_execute_action_to_code(config, action_id, template_arg, args):
|
||||
raise EsphomeError(
|
||||
f"Missing parameter: '{name}' in script.execute {config[CONF_ID]}"
|
||||
)
|
||||
arg = await cg.templatable(
|
||||
config_args[name], args, type, convert(str(type))
|
||||
)
|
||||
value = config_args[name]
|
||||
if cg.is_template(value):
|
||||
arg = await automation.call_user_lambda(value, args, type)
|
||||
else:
|
||||
arg = call_lambda(
|
||||
await cg.templatable(value, args, type, convert(str(type)))
|
||||
)
|
||||
script_args.append(arg)
|
||||
return script_args
|
||||
|
||||
@@ -255,14 +260,13 @@ async def script_execute_action_to_code(config, action_id, template_arg, args):
|
||||
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
# Separate statements, because the order of evaluation inside one call is not defined
|
||||
names = [cg.MockObj(f"esphome__arg_{index}") for index in range(len(script_args))]
|
||||
statements = [
|
||||
f"auto esphome__arg_{index} = {automation.immediate_lambda_call(arg)};"
|
||||
for index, arg in enumerate(script_args)
|
||||
str(cg.statement(AssignmentExpression("auto", "", name, arg)))
|
||||
for name, arg in zip(names, script_args, strict=True)
|
||||
]
|
||||
names = ", ".join(
|
||||
f"std::move(esphome__arg_{index})" for index in range(len(script_args))
|
||||
)
|
||||
statements.append(f"{automation.parent_ref(paren)}->execute({names});")
|
||||
moved = [cg.std_ns.move(name) for name in names]
|
||||
statements.append(str(cg.statement(automation.parent_ref(paren).execute(*moved))))
|
||||
return automation.apply_statements_action(action_id, template_arg, args, statements)
|
||||
|
||||
|
||||
|
||||
@@ -106,8 +106,8 @@ def test_rc_switch_raw(bodies: list[str]) -> None:
|
||||
lambda_ = bodies[6]
|
||||
_in_order(
|
||||
lambda_,
|
||||
"const std::string esphome__code = []() -> std::string {\n"
|
||||
' return std::string("0010100110");',
|
||||
# A lambda naming no argument is reduced to its expression
|
||||
'const std::string esphome__code = static_cast<std::string>(std::string("0010100110"));',
|
||||
"remote_base::rc_switch_protocol(1).transmit(esphome__call.get_data(), "
|
||||
"remote_base::decode_binary_string(esphome__code), esphome__code.size());",
|
||||
"esphome__call.set_send_times(2);",
|
||||
@@ -140,9 +140,9 @@ def test_rc_switch_type_a(bodies: list[str]) -> None:
|
||||
_in_order(
|
||||
bodies[8],
|
||||
"const auto esphome__group = remote_base::decode_binary_string("
|
||||
'[]() -> std::string {\n return std::string("11001");',
|
||||
'static_cast<std::string>(std::string("11001")));',
|
||||
"const auto esphome__device = remote_base::decode_binary_string(",
|
||||
"const auto esphome__state = []() -> bool {\n return false;",
|
||||
"const auto esphome__state = static_cast<bool>(false);",
|
||||
"remote_base::RCSwitchBase::type_a_code(esphome__group, esphome__device, "
|
||||
"esphome__state, &esphome__code, &esphome__nbits);",
|
||||
"remote_base::rc_switch_protocol(1).transmit(",
|
||||
@@ -163,11 +163,12 @@ def test_rc_switch_type_c(bodies: list[str]) -> None:
|
||||
) in bodies[10]
|
||||
_in_order(
|
||||
bodies[11],
|
||||
# A bare expression is cast to the lambda's type, so it binds as an operand
|
||||
"const auto esphome__family = static_cast<uint8_t>(tolower("
|
||||
"[]() -> std::string {\n return std::string(\"C\");\n }()[0]) - 'a');",
|
||||
"const auto esphome__group = []() -> uint8_t {",
|
||||
"const auto esphome__device = []() -> uint8_t {",
|
||||
"const auto esphome__state = []() -> bool {",
|
||||
"static_cast<std::string>(std::string(\"C\"))[0]) - 'a');",
|
||||
"const auto esphome__group = static_cast<uint8_t>(1);",
|
||||
"const auto esphome__device = static_cast<uint8_t>(2);",
|
||||
"const auto esphome__state = static_cast<bool>(true);",
|
||||
"remote_base::RCSwitchBase::type_c_code(esphome__family, esphome__group, "
|
||||
"esphome__device, esphome__state, &esphome__code, &esphome__nbits);",
|
||||
)
|
||||
@@ -180,7 +181,7 @@ def test_rc_switch_type_d(bodies: list[str]) -> None:
|
||||
) in bodies[12]
|
||||
assert (
|
||||
"const auto esphome__group = static_cast<uint8_t>(tolower("
|
||||
"[]() -> std::string {\n return std::string(\"b\");\n }()[0]) - 'a');"
|
||||
"static_cast<std::string>(std::string(\"b\"))[0]) - 'a');"
|
||||
) in bodies[13]
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ esphome:
|
||||
then:
|
||||
- rp2_ble_tracker.start_scan:
|
||||
continuous: true
|
||||
- rp2_ble_tracker.start_scan:
|
||||
continuous: !lambda return millis() > 0;
|
||||
# Bare form: passes the configured scan_parameters mode (asserted in the codegen test).
|
||||
- rp2_ble_tracker.start_scan:
|
||||
- rp2_ble_tracker.stop_scan
|
||||
|
||||
@@ -42,6 +42,11 @@ def test_trigger_codegen(
|
||||
main_cpp.count("::rp2_ble_tracker_rp2bletracker_id->configured_continuous());")
|
||||
== 1
|
||||
)
|
||||
# A continuous lambda naming no trigger argument is reduced to its expression
|
||||
assert (
|
||||
"ble_device_base::start_scan(::rp2_ble_tracker_rp2bletracker_id, "
|
||||
"static_cast<bool>(millis() > 0));"
|
||||
) in main_cpp
|
||||
assert main_cpp.count("->stop_scan();") == 1
|
||||
# scan_parameters continuous: false reaches the YAML-mode setter, not the
|
||||
# runtime override.
|
||||
|
||||
@@ -105,7 +105,11 @@ def test_parameters_by_value(generate_main) -> None:
|
||||
)
|
||||
body = _function_body(main_cpp, name)
|
||||
assert body.count("[](int x, std::string s) -> void {") == 2
|
||||
assert body.count("[](int x, std::string s) -> int {") == 2
|
||||
# A lambda passed to another script copies only the parameters it names
|
||||
assert (
|
||||
body.count("[](int x, const std::remove_cvref_t<std::string> & s) -> int {")
|
||||
== 2
|
||||
)
|
||||
assert "x *= 2;\n ESP_LOGI(" in body
|
||||
assert '"BY_VALUE again %d", x *= 2' in body
|
||||
assert "return x *= 2;" in body
|
||||
|
||||
Reference in new issue
Block a user