1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-07 10:31:49 +00:00

[component] Add is_idle method and condition (#11651)

This commit is contained in:
Clyde Stubbs
2025-11-03 10:33:44 +10:00
committed by GitHub
parent 86402be9e3
commit 19e275dc02
6 changed files with 45 additions and 4 deletions

View File

@@ -15,7 +15,7 @@ from esphome.const import (
CONF_TYPE_ID, CONF_TYPE_ID,
CONF_UPDATE_INTERVAL, CONF_UPDATE_INTERVAL,
) )
from esphome.core import ID from esphome.core import ID, Lambda
from esphome.cpp_generator import ( from esphome.cpp_generator import (
LambdaExpression, LambdaExpression,
MockObj, MockObj,
@@ -310,6 +310,30 @@ async def for_condition_to_code(
return var return var
@register_condition(
"component.is_idle",
LambdaCondition,
maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(cg.Component),
}
),
)
async def component_is_idle_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
comp = await cg.get_variable(config[CONF_ID])
lambda_ = await cg.process_lambda(
Lambda(f"return {comp}->is_idle();"), args, return_type=bool
)
return new_lambda_pvariable(
condition_id, lambda_, StatelessLambdaCondition, template_arg
)
@register_action( @register_action(
"delay", DelayAction, cv.templatable(cv.positive_time_period_milliseconds) "delay", DelayAction, cv.templatable(cv.positive_time_period_milliseconds)
) )

View File

@@ -137,7 +137,11 @@ async def lvgl_is_idle(config, condition_id, template_arg, args):
lvgl = config[CONF_LVGL_ID] lvgl = config[CONF_LVGL_ID]
timeout = await lv_milliseconds.process(config[CONF_TIMEOUT]) timeout = await lv_milliseconds.process(config[CONF_TIMEOUT])
async with LambdaContext(LVGL_COMP_ARG, return_type=cg.bool_) as context: async with LambdaContext(LVGL_COMP_ARG, return_type=cg.bool_) as context:
lv_add(ReturnStatement(lvgl_comp.is_idle(timeout))) lv_add(
ReturnStatement(
lv_expr.disp_get_inactive_time(lvgl_comp.get_disp()) > timeout
)
)
var = cg.new_Pvariable( var = cg.new_Pvariable(
condition_id, condition_id,
TemplateArguments(LvglComponent, *template_arg), TemplateArguments(LvglComponent, *template_arg),

View File

@@ -175,7 +175,6 @@ class LvglComponent : public PollingComponent {
static void monitor_cb(lv_disp_drv_t *disp_drv, uint32_t time, uint32_t px); static void monitor_cb(lv_disp_drv_t *disp_drv, uint32_t time, uint32_t px);
static void render_start_cb(lv_disp_drv_t *disp_drv); static void render_start_cb(lv_disp_drv_t *disp_drv);
void dump_config() override; void dump_config() override;
bool is_idle(uint32_t idle_ms) { return lv_disp_get_inactive_time(this->disp_) > idle_ms; }
lv_disp_t *get_disp() { return this->disp_; } lv_disp_t *get_disp() { return this->disp_; }
lv_obj_t *get_scr_act() { return lv_disp_get_scr_act(this->disp_); } lv_obj_t *get_scr_act() { return lv_disp_get_scr_act(this->disp_); }
// Pause or resume the display. // Pause or resume the display.

View File

@@ -284,6 +284,7 @@ bool Component::is_ready() const {
(this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE || (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE ||
(this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_SETUP; (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_SETUP;
} }
bool Component::is_idle() const { return (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE; }
bool Component::can_proceed() { return true; } bool Component::can_proceed() { return true; }
bool Component::status_has_warning() const { return this->component_state_ & STATUS_LED_WARNING; } bool Component::status_has_warning() const { return this->component_state_ & STATUS_LED_WARNING; }
bool Component::status_has_error() const { return this->component_state_ & STATUS_LED_ERROR; } bool Component::status_has_error() const { return this->component_state_ & STATUS_LED_ERROR; }

View File

@@ -141,6 +141,14 @@ class Component {
*/ */
bool is_in_loop_state() const; bool is_in_loop_state() const;
/** Check if this component is idle.
* Being idle means being in LOOP_DONE state.
* This means the component has completed setup, is not failed, but its loop is currently disabled.
*
* @return True if the component is idle
*/
bool is_idle() const;
/** Mark this component as failed. Any future timeouts/intervals/setup/loop will no longer be called. /** Mark this component as failed. Any future timeouts/intervals/setup/loop will no longer be called.
* *
* This might be useful if a component wants to indicate that a connection to its peripheral failed. * This might be useful if a component wants to indicate that a connection to its peripheral failed.

View File

@@ -10,7 +10,11 @@ esphome:
on_shutdown: on_shutdown:
logger.log: on_shutdown logger.log: on_shutdown
on_loop: on_loop:
logger.log: on_loop if:
condition:
component.is_idle: binary_sensor_id
then:
logger.log: on_loop - sensor idle
compile_process_limit: 1 compile_process_limit: 1
min_version: "2025.1" min_version: "2025.1"
name_add_mac_suffix: true name_add_mac_suffix: true
@@ -34,5 +38,6 @@ esphome:
binary_sensor: binary_sensor:
- platform: template - platform: template
id: binary_sensor_id
name: Other device sensor name: Other device sensor
device_id: other_device device_id: other_device