Add optional timeout for wait_until action (#2282)

This commit is contained in:
Jesse Hills 2021-10-13 08:23:24 +13:00 committed by GitHub
parent 1184bbc976
commit 34db9d9ef2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 6 deletions

View file

@ -6,6 +6,7 @@ from esphome.const import (
CONF_ELSE, CONF_ELSE,
CONF_ID, CONF_ID,
CONF_THEN, CONF_THEN,
CONF_TIMEOUT,
CONF_TRIGGER_ID, CONF_TRIGGER_ID,
CONF_TYPE_ID, CONF_TYPE_ID,
CONF_TIME, CONF_TIME,
@ -244,6 +245,9 @@ def validate_wait_until(value):
schema = cv.Schema( schema = cv.Schema(
{ {
cv.Required(CONF_CONDITION): validate_potentially_and_condition, cv.Required(CONF_CONDITION): validate_potentially_and_condition,
cv.Optional(CONF_TIMEOUT): cv.templatable(
cv.positive_time_period_milliseconds
),
} }
) )
if isinstance(value, dict) and CONF_CONDITION in value: if isinstance(value, dict) and CONF_CONDITION in value:
@ -255,6 +259,9 @@ def validate_wait_until(value):
async def wait_until_action_to_code(config, action_id, template_arg, args): async def wait_until_action_to_code(config, action_id, template_arg, args):
conditions = await build_condition(config[CONF_CONDITION], template_arg, args) conditions = await build_condition(config[CONF_CONDITION], template_arg, args)
var = cg.new_Pvariable(action_id, template_arg, conditions) var = cg.new_Pvariable(action_id, template_arg, conditions)
if CONF_TIMEOUT in config:
template_ = await cg.templatable(config[CONF_TIMEOUT], args, cg.uint32)
cg.add(var.set_timeout_value(template_))
await cg.register_component(var, {}) await cg.register_component(var, {})
return var return var

View file

@ -228,6 +228,8 @@ template<typename... Ts> class WaitUntilAction : public Action<Ts...>, public Co
public: public:
WaitUntilAction(Condition<Ts...> *condition) : condition_(condition) {} WaitUntilAction(Condition<Ts...> *condition) : condition_(condition) {}
TEMPLATABLE_VALUE(uint32_t, timeout_value)
void play_complex(Ts... x) override { void play_complex(Ts... x) override {
this->num_running_++; this->num_running_++;
// Check if we can continue immediately. // Check if we can continue immediately.
@ -238,6 +240,12 @@ template<typename... Ts> class WaitUntilAction : public Action<Ts...>, public Co
return; return;
} }
this->var_ = std::make_tuple(x...); this->var_ = std::make_tuple(x...);
if (this->timeout_value_.has_value()) {
auto f = std::bind(&WaitUntilAction<Ts...>::play_next_, this, x...);
this->set_timeout("timeout", this->timeout_value_.value(x...), f);
}
this->loop(); this->loop();
} }
@ -249,6 +257,8 @@ template<typename... Ts> class WaitUntilAction : public Action<Ts...>, public Co
return; return;
} }
this->cancel_timeout("timeout");
this->play_next_tuple_(this->var_); this->play_next_tuple_(this->var_);
} }
@ -257,6 +267,8 @@ template<typename... Ts> class WaitUntilAction : public Action<Ts...>, public Co
void play(Ts... x) override { /* ignore - see play_complex */ void play(Ts... x) override { /* ignore - see play_complex */
} }
void stop() override { this->cancel_timeout("timeout"); }
protected: protected:
Condition<Ts...> *condition_; Condition<Ts...> *condition_;
std::tuple<Ts...> var_{}; std::tuple<Ts...> var_{};

View file

@ -364,8 +364,11 @@ sensor:
then: then:
- lambda: >- - lambda: >-
ESP_LOGD("main", "Got value range %f", x); ESP_LOGD("main", "Got value range %f", x);
- wait_until: wifi.connected
- wait_until: - wait_until:
condition:
binary_sensor.is_on: binary_sensor1 binary_sensor.is_on: binary_sensor1
timeout: 1s
on_raw_value: on_raw_value:
- lambda: >- - lambda: >-
ESP_LOGD("main", "Got raw value %f", x); ESP_LOGD("main", "Got raw value %f", x);

View file

@ -5,10 +5,13 @@ esphome:
board: d1_mini board: d1_mini
build_path: build/test3 build_path: build/test3
on_boot: on_boot:
- wait_until: - if:
condition:
- api.connected - api.connected
- wifi.connected - wifi.connected
- time.has_time - time.has_time
then:
- logger.log: "Have time"
includes: includes:
- custom.h - custom.h
@ -1291,4 +1294,3 @@ dsmr:
daly_bms: daly_bms:
update_interval: 20s update_interval: 20s
uart_id: uart1 uart_id: uart1