mirror of
https://github.com/esphome/esphome.git
synced 2026-10-07 03:16:37 +00:00
Merge branch 'dev' into climate_store_flash
This commit is contained in:
@@ -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']
|
||||
Reference in New Issue
Block a user