mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 02:02:51 +00:00
[nextion] Pass std::string to custom-protocol automations that defer (#20571)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0c645ac3a1
commit
ba9061e34e
@@ -11,6 +11,7 @@ from esphome.const import (
|
||||
PLATFORM_ESP8266,
|
||||
)
|
||||
from esphome.core import CORE, TimePeriod
|
||||
from esphome.types import ConfigType, TemplateArgsType
|
||||
|
||||
from . import FILTER_SOURCE_FILES, Nextion, nextion_ns, nextion_ref # noqa: F401 pylint: disable=unused-import
|
||||
from .base_component import (
|
||||
@@ -177,6 +178,10 @@ _CALLBACK_AUTOMATIONS = (
|
||||
automation.CallbackAutomation(
|
||||
CONF_ON_BUFFER_OVERFLOW, "add_buffer_overflow_event_callback"
|
||||
),
|
||||
)
|
||||
|
||||
# The strings live only while the callback runs
|
||||
_CUSTOM_CALLBACK_AUTOMATIONS = (
|
||||
automation.CallbackAutomation(
|
||||
CONF_ON_CUSTOM_BINARY_SENSOR,
|
||||
"add_custom_binary_sensor_callback",
|
||||
@@ -293,3 +298,18 @@ async def to_code(config):
|
||||
cg.add_define(define_name)
|
||||
|
||||
await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS)
|
||||
for entry in _CUSTOM_CALLBACK_AUTOMATIONS:
|
||||
for conf in config.get(entry.conf_key, []):
|
||||
await automation.build_callback_automation(
|
||||
var, entry.callback_method, _owning_args(entry.args, conf), conf
|
||||
)
|
||||
|
||||
|
||||
def _owning_args(args: TemplateArgsType, conf: ConfigType) -> TemplateArgsType:
|
||||
"""Pass std::string instead of StringRef to an automation that defers, as it keeps its arguments."""
|
||||
if not automation.has_non_synchronous_actions(conf):
|
||||
return args
|
||||
return [
|
||||
(cg.std_string if type_ is cg.StringRef else type_, name)
|
||||
for type_, name in args
|
||||
]
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
esphome:
|
||||
name: test
|
||||
|
||||
esp32:
|
||||
board: esp32dev
|
||||
framework:
|
||||
type: esp-idf
|
||||
|
||||
uart:
|
||||
tx_pin: 17
|
||||
rx_pin: 16
|
||||
baud_rate: 115200
|
||||
|
||||
display:
|
||||
- platform: nextion
|
||||
on_custom_text_sensor:
|
||||
- then:
|
||||
- lambda: 'ESP_LOGD("test", "%s=%s", key.c_str(), value.c_str());'
|
||||
- then:
|
||||
- delay: 1s
|
||||
- lambda: 'ESP_LOGD("test", "%s=%s", key.c_str(), value.c_str());'
|
||||
@@ -0,0 +1,47 @@
|
||||
"""Tests for the argument types of the nextion custom-protocol triggers."""
|
||||
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.nextion.display import _owning_args
|
||||
from esphome.core import Lambda
|
||||
|
||||
ARGS = [(cg.StringRef, "key"), (cg.bool_, "value")]
|
||||
SYNCHRONOUS_ACTION = {"lambda": Lambda('ESP_LOGD("test", "ran");')}
|
||||
DEFERRING_ACTION = {"delay": "1s"}
|
||||
TRUE_CONDITION = {"lambda": Lambda("return true;")}
|
||||
|
||||
|
||||
def test_synchronous_automation_keeps_string_ref() -> None:
|
||||
assert _owning_args(ARGS, {"then": [SYNCHRONOUS_ACTION]}) == ARGS
|
||||
|
||||
|
||||
def test_deferring_automation_gets_std_string() -> None:
|
||||
assert _owning_args(ARGS, {"then": [SYNCHRONOUS_ACTION, DEFERRING_ACTION]}) == [
|
||||
(cg.std_string, "key"),
|
||||
(cg.bool_, "value"),
|
||||
]
|
||||
|
||||
|
||||
def test_nested_deferring_action_gets_std_string() -> None:
|
||||
actions = [{"if": {"condition": TRUE_CONDITION, "then": [DEFERRING_ACTION]}}]
|
||||
assert _owning_args(ARGS, {"then": actions})[0] == (cg.std_string, "key")
|
||||
|
||||
|
||||
def test_all_string_refs_swapped() -> None:
|
||||
args = [(cg.StringRef, "key"), (cg.StringRef, "value")]
|
||||
assert _owning_args(args, {"then": [DEFERRING_ACTION]}) == [
|
||||
(cg.std_string, "key"),
|
||||
(cg.std_string, "value"),
|
||||
]
|
||||
|
||||
|
||||
def test_generated_automation_types(
|
||||
generate_main: Callable[[str | Path], str],
|
||||
component_config_path: Callable[[str], Path],
|
||||
) -> None:
|
||||
main_cpp = generate_main(component_config_path("custom_triggers.yaml"))
|
||||
|
||||
assert "Automation<StringRef, StringRef>" in main_cpp
|
||||
assert "Automation<std::string, std::string>" in main_cpp
|
||||
@@ -287,13 +287,20 @@ display:
|
||||
then:
|
||||
logger.log: "Nextion reported a buffer overflow!"
|
||||
on_custom_text_sensor:
|
||||
then:
|
||||
- lambda: |-
|
||||
// key: StringRef, value: StringRef
|
||||
if (key == "csv") {
|
||||
// parse value here, or forward to your own component
|
||||
ESP_LOGD("nextion.csv", "Got CSV: %s", value.c_str());
|
||||
}
|
||||
- then:
|
||||
- lambda: |-
|
||||
// key: StringRef, value: StringRef
|
||||
if (key == "csv") {
|
||||
// parse value here, or forward to your own component
|
||||
ESP_LOGD("nextion.csv", "Got CSV: %s", value.c_str());
|
||||
}
|
||||
# Deferring: key and value are passed as std::string
|
||||
- then:
|
||||
- delay: 1s
|
||||
- lambda: |-
|
||||
if (key == "csv") {
|
||||
ESP_LOGD("nextion.csv", "Got CSV earlier: %s", value.c_str());
|
||||
}
|
||||
on_custom_sensor:
|
||||
then:
|
||||
- lambda: |-
|
||||
@@ -308,9 +315,13 @@ display:
|
||||
ESP_LOGD("nextion.btn", "btn1=%s", ONOFF(value));
|
||||
}
|
||||
on_custom_switch:
|
||||
then:
|
||||
- lambda: |-
|
||||
ESP_LOGD("nextion.sw", "%s=%s", key.c_str(), ONOFF(value));
|
||||
- then:
|
||||
- lambda: |-
|
||||
ESP_LOGD("nextion.sw", "%s=%s", key.c_str(), ONOFF(value));
|
||||
- then:
|
||||
- delay: 1s
|
||||
- lambda: |-
|
||||
ESP_LOGD("nextion.sw", "%s was %s", key.c_str(), ONOFF(value));
|
||||
on_page:
|
||||
then:
|
||||
lambda: 'ESP_LOGD("display","Display shows new page %u", x);'
|
||||
|
||||
Reference in New Issue
Block a user