Feat/component poller suspend (#5423)

This commit is contained in:
De Cock Xavier 2023-10-02 22:25:13 +02:00 committed by GitHub
parent 589b9e10b2
commit a33b8abce8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 0 deletions

View file

@ -11,6 +11,7 @@ from esphome.const import (
CONF_TRIGGER_ID,
CONF_TYPE_ID,
CONF_TIME,
CONF_UPDATE_INTERVAL,
)
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
from esphome.util import Registry
@ -69,6 +70,8 @@ WhileAction = cg.esphome_ns.class_("WhileAction", Action)
RepeatAction = cg.esphome_ns.class_("RepeatAction", Action)
WaitUntilAction = cg.esphome_ns.class_("WaitUntilAction", Action, cg.Component)
UpdateComponentAction = cg.esphome_ns.class_("UpdateComponentAction", Action)
SuspendComponentAction = cg.esphome_ns.class_("SuspendComponentAction", Action)
ResumeComponentAction = cg.esphome_ns.class_("ResumeComponentAction", Action)
Automation = cg.esphome_ns.class_("Automation")
LambdaCondition = cg.esphome_ns.class_("LambdaCondition", Condition)
@ -303,6 +306,41 @@ async def component_update_action_to_code(config, action_id, template_arg, args)
return cg.new_Pvariable(action_id, template_arg, comp)
@register_action(
"component.suspend",
SuspendComponentAction,
maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(cg.PollingComponent),
}
),
)
async def component_suspend_action_to_code(config, action_id, template_arg, args):
comp = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, comp)
@register_action(
"component.resume",
ResumeComponentAction,
maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(cg.PollingComponent),
cv.Optional(CONF_UPDATE_INTERVAL): cv.templatable(
cv.positive_time_period_milliseconds
),
}
),
)
async def component_resume_action_to_code(config, action_id, template_arg, args):
comp = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, comp)
if CONF_UPDATE_INTERVAL in config:
template_ = await cg.templatable(config[CONF_UPDATE_INTERVAL], args, int)
cg.add(var.set_update_interval(template_))
return var
async def build_action(full_config, template_arg, args):
registry_entry, config = cg.extract_registry_entry_config(
ACTION_REGISTRY, full_config

View file

@ -330,4 +330,38 @@ template<typename... Ts> class UpdateComponentAction : public Action<Ts...> {
PollingComponent *component_;
};
template<typename... Ts> class SuspendComponentAction : public Action<Ts...> {
public:
SuspendComponentAction(PollingComponent *component) : component_(component) {}
void play(Ts... x) override {
if (!this->component_->is_ready())
return;
this->component_->stop_poller();
}
protected:
PollingComponent *component_;
};
template<typename... Ts> class ResumeComponentAction : public Action<Ts...> {
public:
ResumeComponentAction(PollingComponent *component) : component_(component) {}
TEMPLATABLE_VALUE(uint32_t, update_interval)
void play(Ts... x) override {
if (!this->component_->is_ready()) {
return;
}
optional<uint32_t> update_interval = this->update_interval_.optional_value(x...);
if (update_interval.has_value()) {
this->component_->set_update_interval(update_interval.value());
}
this->component_->start_poller();
}
protected:
PollingComponent *component_;
};
} // namespace esphome

View file

@ -188,10 +188,20 @@ void PollingComponent::call_setup() {
// Let the polling component subclass setup their HW.
this->setup();
// init the poller
this->start_poller();
}
void PollingComponent::start_poller() {
// Register interval.
this->set_interval("update", this->get_update_interval(), [this]() { this->update(); });
}
void PollingComponent::stop_poller() {
// Clear the interval to suspend component
this->cancel_interval("update");
}
uint32_t PollingComponent::get_update_interval() const { return this->update_interval_; }
void PollingComponent::set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }

View file

@ -308,6 +308,12 @@ class PollingComponent : public Component {
/// Get the update interval in ms of this sensor
virtual uint32_t get_update_interval() const;
// Start the poller, used for component.suspend
void start_poller();
// Stop the poller, used for component.suspend
void stop_poller();
protected:
uint32_t update_interval_;
};

View file

@ -3566,6 +3566,22 @@ button:
name: Midea Power Inverse
on_press:
midea_ac.power_toggle:
- platform: template
name: Poller component suspend test
on_press:
- component.suspend: myteleinfo
- delay: 20s
- component.update: myteleinfo
- delay: 20s
- component.resume: myteleinfo
- delay: 20s
- component.resume:
id: myteleinfo
update_interval: 2s
- delay: 20s
- component.resume:
id: myteleinfo
update_interval: !lambda return 2500;
- platform: ld2410
factory_reset:
name: "factory reset"