Merge branch 'dev' into climate_store_flash

This commit is contained in:
J. Nick Koston
2025-11-02 19:48:42 -06:00
committed by GitHub
75 changed files with 2155 additions and 651 deletions
@@ -0,0 +1,105 @@
esphome:
name: action-concurrent-reentry
on_boot:
- priority: -100
then:
- repeat:
count: 5
then:
- lambda: id(handler_wait_until)->execute(id(global_counter));
- lambda: id(handler_repeat)->execute(id(global_counter));
- lambda: id(handler_while)->execute(id(global_counter));
- lambda: id(handler_script_wait)->execute(id(global_counter));
- delay: 50ms
- lambda: id(global_counter)++;
- delay: 50ms
host:
api:
globals:
- id: global_counter
type: int
script:
- id: handler_wait_until
mode: parallel
parameters:
arg: int
then:
- wait_until:
condition:
lambda: return id(global_counter) == 5;
- logger.log:
format: "AFTER wait_until ARG %d"
args:
- arg
- id: handler_script_wait
mode: parallel
parameters:
arg: int
then:
- script.wait: handler_wait_until
- logger.log:
format: "AFTER script.wait ARG %d"
args:
- arg
- id: handler_repeat
mode: parallel
parameters:
arg: int
then:
- repeat:
count: 3
then:
- logger.log:
format: "IN repeat %d ARG %d"
args:
- iteration
- arg
- delay: 100ms
- logger.log:
format: "AFTER repeat ARG %d"
args:
- arg
- id: handler_while
mode: parallel
parameters:
arg: int
then:
- while:
condition:
lambda: return id(global_counter) != 5;
then:
- logger.log:
format: "IN while ARG %d"
args:
- arg
- delay: 100ms
- logger.log:
format: "AFTER while ARG %d"
args:
- arg
logger:
level: DEBUG
@@ -0,0 +1,130 @@
esphome:
name: test-automation-wait-actions
host:
api:
actions:
# Test 1: Trigger wait_until automation 5 times rapidly
- action: test_wait_until
then:
- logger.log: "=== TEST 1: Triggering wait_until automation 5 times ==="
# Publish 5 different values to trigger the on_value automation 5 times
- sensor.template.publish:
id: wait_until_sensor
state: 1
- sensor.template.publish:
id: wait_until_sensor
state: 2
- sensor.template.publish:
id: wait_until_sensor
state: 3
- sensor.template.publish:
id: wait_until_sensor
state: 4
- sensor.template.publish:
id: wait_until_sensor
state: 5
# Wait then satisfy the condition so all 5 waiting actions complete
- delay: 100ms
- globals.set:
id: test_flag
value: 'true'
# Test 2: Trigger script.wait automation 5 times rapidly
- action: test_script_wait
then:
- logger.log: "=== TEST 2: Triggering script.wait automation 5 times ==="
# Start a long-running script
- script.execute: blocking_script
# Publish 5 different values to trigger the on_value automation 5 times
- sensor.template.publish:
id: script_wait_sensor
state: 1
- sensor.template.publish:
id: script_wait_sensor
state: 2
- sensor.template.publish:
id: script_wait_sensor
state: 3
- sensor.template.publish:
id: script_wait_sensor
state: 4
- sensor.template.publish:
id: script_wait_sensor
state: 5
# Test 3: Trigger wait_until timeout automation 5 times rapidly
- action: test_wait_timeout
then:
- logger.log: "=== TEST 3: Triggering timeout automation 5 times ==="
# Publish 5 different values (condition will never be true, all will timeout)
- sensor.template.publish:
id: timeout_sensor
state: 1
- sensor.template.publish:
id: timeout_sensor
state: 2
- sensor.template.publish:
id: timeout_sensor
state: 3
- sensor.template.publish:
id: timeout_sensor
state: 4
- sensor.template.publish:
id: timeout_sensor
state: 5
logger:
level: DEBUG
globals:
- id: test_flag
type: bool
restore_value: false
initial_value: 'false'
- id: timeout_flag
type: bool
restore_value: false
initial_value: 'false'
# Sensors with wait_until/script.wait in their on_value automations
sensor:
# Test 1: on_value automation with wait_until
- platform: template
id: wait_until_sensor
on_value:
# This wait_until will be hit 5 times before any complete
- wait_until:
condition:
lambda: return id(test_flag);
- logger.log: "wait_until automation completed"
# Test 2: on_value automation with script.wait
- platform: template
id: script_wait_sensor
on_value:
# This script.wait will be hit 5 times before any complete
- script.wait: blocking_script
- logger.log: "script.wait automation completed"
# Test 3: on_value automation with wait_until timeout
- platform: template
id: timeout_sensor
on_value:
# This wait_until will be hit 5 times, all will timeout
- wait_until:
condition:
lambda: return id(timeout_flag);
timeout: 200ms
- logger.log: "timeout automation completed"
script:
# Blocking script for script.wait test
- id: blocking_script
mode: single
then:
- logger.log: "Blocking script: START"
- delay: 200ms
- logger.log: "Blocking script: END"
@@ -0,0 +1,174 @@
esphome:
name: test-continuation-actions
host:
api:
actions:
# Test 1: IfAction with ContinuationAction (then/else branches)
- action: test_if_action
variables:
condition: bool
value: int
then:
- logger.log:
format: "Test if: condition=%s, value=%d"
args: ['YESNO(condition)', 'value']
- if:
condition:
lambda: 'return condition;'
then:
- logger.log:
format: "if-then executed: value=%d"
args: ['value']
else:
- logger.log:
format: "if-else executed: value=%d"
args: ['value']
- logger.log: "if completed"
# Test 2: Nested IfAction (multiple ContinuationAction instances)
- action: test_nested_if
variables:
outer: bool
inner: bool
then:
- logger.log:
format: "Test nested if: outer=%s, inner=%s"
args: ['YESNO(outer)', 'YESNO(inner)']
- if:
condition:
lambda: 'return outer;'
then:
- if:
condition:
lambda: 'return inner;'
then:
- logger.log: "nested-both-true"
else:
- logger.log: "nested-outer-true-inner-false"
else:
- logger.log: "nested-outer-false"
- logger.log: "nested if completed"
# Test 3: WhileAction with WhileLoopContinuation
- action: test_while_action
variables:
max_count: int
then:
- logger.log:
format: "Test while: max_count=%d"
args: ['max_count']
- globals.set:
id: continuation_test_counter
value: !lambda 'return 0;'
- while:
condition:
lambda: 'return id(continuation_test_counter) < max_count;'
then:
- logger.log:
format: "while-iteration-%d"
args: ['id(continuation_test_counter)']
- globals.set:
id: continuation_test_counter
value: !lambda 'return id(continuation_test_counter) + 1;'
- logger.log: "while completed"
# Test 4: RepeatAction with RepeatLoopContinuation
- action: test_repeat_action
variables:
count: int
then:
- logger.log:
format: "Test repeat: count=%d"
args: ['count']
- repeat:
count: !lambda 'return count;'
then:
- logger.log:
format: "repeat-iteration-%d"
args: ['iteration']
- logger.log: "repeat completed"
# Test 5: Combined continuations (if + while + repeat)
- action: test_combined
variables:
do_loop: bool
loop_count: int
then:
- logger.log:
format: "Test combined: do_loop=%s, loop_count=%d"
args: ['YESNO(do_loop)', 'loop_count']
- if:
condition:
lambda: 'return do_loop;'
then:
- repeat:
count: !lambda 'return loop_count;'
then:
- globals.set:
id: continuation_test_counter
value: !lambda 'return iteration;'
- while:
condition:
lambda: 'return id(continuation_test_counter) > 0;'
then:
- logger.log:
format: "combined-repeat%d-while%d"
args: ['iteration', 'id(continuation_test_counter)']
- globals.set:
id: continuation_test_counter
value: !lambda 'return id(continuation_test_counter) - 1;'
else:
- logger.log: "combined-skipped"
- logger.log: "combined completed"
# Test 6: Rapid triggers to verify memory efficiency
- action: test_rapid_if
then:
- logger.log: "=== Rapid if test start ==="
- sensor.template.publish:
id: rapid_sensor
state: 1
- sensor.template.publish:
id: rapid_sensor
state: 2
- sensor.template.publish:
id: rapid_sensor
state: 3
- sensor.template.publish:
id: rapid_sensor
state: 4
- sensor.template.publish:
id: rapid_sensor
state: 5
- logger.log: "=== Rapid if test published 5 values ==="
logger:
level: DEBUG
globals:
- id: continuation_test_counter
type: int
restore_value: false
initial_value: '0'
# Sensor to test rapid automation triggers with if/else (ContinuationAction)
sensor:
- platform: template
id: rapid_sensor
on_value:
- if:
condition:
lambda: 'return x > 2;'
then:
- logger.log:
format: "rapid-if-then: value=%d"
args: ['(int)x']
else:
- logger.log:
format: "rapid-if-else: value=%d"
args: ['(int)x']
- logger.log:
format: "rapid-if-completed: value=%d"
args: ['(int)x']