Skip to content

Commit

Permalink
Merge pull request #6 from hostcc/feature/disable-schedule
Browse files Browse the repository at this point in the history
Implement disabling scheduled actions
  • Loading branch information
hostcc authored Aug 3, 2023
2 parents d9a9f15 + a789ef3 commit ad90ba6
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 32 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Multiple instances of the component are supported.
* **fri** (*Required*, [Switch](https://esphome.io/index.html#switch-components)): Similarly but for Friday
* **sat** (*Required*, [Switch](https://esphome.io/index.html#switch-components)): Similarly but for Saturday
* **sun** (*Required*, [Switch](https://esphome.io/index.html#switch-components)): Similarly but for Sunday
* **disabled** (*Required*, [Switch](https://esphome.io/index.html#switch-components)): Component to disable scheduled actions
* **on_time** (*Requred*, [Automation](https://esphome.io/guides/automations.html#automation)) Automation to run when schedule triggers

## Example
Expand All @@ -53,49 +54,48 @@ switch:
id: lawn_sprinklers_mon
name: "Lawn sprinklers: Mon"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_tue
name: "Lawn sprinklers: Tue"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_wed
name: "Lawn sprinklers: Wed"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_thu
name: "Lawn sprinklers: Thu"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_fri
name: "Lawn sprinklers: Fri"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_sat
name: "Lawn sprinklers: Sat"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_sun
name: "Lawn sprinklers: Sun"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_disabled
name: "Lawn sprinklers: Disable"
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
Expand Down Expand Up @@ -139,6 +139,7 @@ dynamic_on_time:
fri: lawn_sprinklers_fri
sat: lawn_sprinklers_sat
sun: lawn_sprinklers_sun
disabled: lawn_sprinklers_disabled
on_time:
- logger.log:
format: 'schedule: Starting full sprinkler cycle'
Expand Down
3 changes: 3 additions & 0 deletions components/dynamic_on_time/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
CONF_FRI = 'fri'
CONF_SAT = 'sat'
CONF_SUN = 'sun'
CONF_DISABLED = 'disabled'

dynamic_on_time_ns = cg.esphome_ns.namespace("dynamic_on_time")
DynamicOnTimeComponent = dynamic_on_time_ns.class_(
Expand All @@ -45,6 +46,7 @@
cv.Required(CONF_FRI): cv.use_id(Switch),
cv.Required(CONF_SAT): cv.use_id(Switch),
cv.Required(CONF_SUN): cv.use_id(Switch),
cv.Required(CONF_DISABLED): cv.use_id(Switch),
cv.Required(CONF_ON_TIME): automation.validate_automation({}),
}).extend(cv.COMPONENT_SCHEMA)

Expand All @@ -71,6 +73,7 @@ async def to_code(config):
await cg.get_variable(config[CONF_FRI]),
await cg.get_variable(config[CONF_SAT]),
await cg.get_variable(config[CONF_SUN]),
await cg.get_variable(config[CONF_DISABLED]),
actions,
)
await cg.register_component(var, config)
44 changes: 28 additions & 16 deletions components/dynamic_on_time/dynamic_on_time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ DynamicOnTime::DynamicOnTime(
switch_::Switch *fri,
switch_::Switch *sat,
switch_::Switch *sun,
switch_::Switch *disabled,
std::vector<esphome::Action<> *> actions):
rtc_(rtc),
hour_(hour), minute_(minute),
mon_(mon), tue_(tue), wed_(wed), thu_(thu), fri_(fri), sat_(sat),
sun_(sun), actions_(actions) {}
sun_(sun), disabled_(disabled), actions_(actions) {}

std::vector<uint8_t> DynamicOnTime::flags_to_days_of_week_(
bool mon, bool tue, bool wed, bool thu, bool fri, bool sat, bool sun
Expand Down Expand Up @@ -67,9 +68,9 @@ void DynamicOnTime::setup() {

for (switch_::Switch *comp : {
this->mon_, this->tue_, this->wed_, this->thu_, this->fri_, this->sat_,
this->sun_
this->sun_, this->disabled_
}) {
comp->add_on_state_callback([this](float value) {
comp->add_on_state_callback([this](bool value) {
this->update_schedule_();
});
}
Expand All @@ -88,13 +89,23 @@ void DynamicOnTime::update_schedule_() {
this->trigger_ = new time::CronTrigger(this->rtc_);
}

// (Re)create the automation instance
if (this->automation_ != nullptr)
// (Re)create the automation instance but only if scheduled actions aren't
// disabled
if (this->automation_ != nullptr) {
delete this->automation_;
this->automation_ = new Automation<>(this->trigger_);
// Add requested actions to it
this->automation_->add_actions(this->actions_);
this->automation_ = nullptr;
}

if (!this->disabled_->state) {
this->automation_ = new Automation<>(this->trigger_);
// Add requested actions to it
this->automation_->add_actions(this->actions_);
}

// All remaining logic is active regardless of scheduled actions are
// disabled, since callbacks from Switch/Number components being active still
// need to be processed otherwise inputs will be lost
//
// Set trigger to fire on zeroth second of configured time
this->trigger_->add_second(0);
// Enable all days of months for the schedule
Expand Down Expand Up @@ -123,7 +134,7 @@ void DynamicOnTime::update_schedule_() {
}

optional<ESPTime> DynamicOnTime::get_next_schedule() {
if (this->days_of_week_.empty())
if (this->disabled_->state || this->days_of_week_.empty())
return {};

ESPTime now = this->rtc_->now();
Expand Down Expand Up @@ -161,6 +172,7 @@ optional<ESPTime> DynamicOnTime::get_next_schedule() {

void DynamicOnTime::dump_config() {
ESP_LOGCONFIG(tag, "Cron trigger details:");
ESP_LOGCONFIG(tag, "Disabled: %s", ONOFF(this->disabled_->state));
ESP_LOGCONFIG(
tag, "Hour (source: '%s'): %.0f",
this->hour_->get_name().c_str(), this->hour_->state);
Expand All @@ -169,25 +181,25 @@ void DynamicOnTime::dump_config() {
this->minute_->get_name().c_str(), this->minute_->state);
ESP_LOGCONFIG(
tag, "Mon (source: '%s'): %s",
this->mon_->get_name().c_str(), this->mon_->state ? "Yes": "No");
this->mon_->get_name().c_str(), ONOFF(this->mon_->state));
ESP_LOGCONFIG(
tag, "Tue (source: '%s'): %s",
this->tue_->get_name().c_str(), this->tue_->state ? "Yes": "No");
this->tue_->get_name().c_str(), ONOFF(this->tue_->state));
ESP_LOGCONFIG(
tag, "Wed (source: '%s'): %s",
this->wed_->get_name().c_str(), this->wed_->state ? "Yes": "No");
this->wed_->get_name().c_str(), ONOFF(this->wed_->state));
ESP_LOGCONFIG(
tag, "Thu (source: '%s'): %s",
this->thu_->get_name().c_str(), this->thu_->state ? "Yes": "No");
this->thu_->get_name().c_str(), ONOFF(this->thu_->state));
ESP_LOGCONFIG(
tag, "Fri (source: '%s'): %s",
this->fri_->get_name().c_str(), this->fri_->state ? "Yes": "No");
this->fri_->get_name().c_str(), ONOFF(this->fri_->state));
ESP_LOGCONFIG(
tag, "Sat (source: '%s'): %s",
this->sat_->get_name().c_str(), this->sat_->state ? "Yes": "No");
this->sat_->get_name().c_str(), ONOFF(this->sat_->state));
ESP_LOGCONFIG(
tag, "Sun (source: '%s'): %s",
this->sun_->get_name().c_str(), this->sun_->state ? "Yes": "No");
this->sun_->get_name().c_str(), ONOFF(this->sun_->state));

auto schedule = this->get_next_schedule();
if (schedule.has_value())
Expand Down
3 changes: 2 additions & 1 deletion components/dynamic_on_time/dynamic_on_time.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class DynamicOnTime : public Component {
explicit DynamicOnTime(
time::RealTimeClock *, number::Number *, number::Number *,
switch_::Switch *, switch_::Switch *, switch_::Switch *, switch_::Switch *,
switch_::Switch *, switch_::Switch *, switch_::Switch *,
switch_::Switch *, switch_::Switch *, switch_::Switch *, switch_::Switch *,
std::vector<esphome::Action<> *>);

void setup() override;
Expand All @@ -35,6 +35,7 @@ class DynamicOnTime : public Component {
switch_::Switch *fri_;
switch_::Switch *sat_;
switch_::Switch *sun_;
switch_::Switch *disabled_;
std::vector<esphome::Action<> *> actions_;
time::CronTrigger *trigger_{nullptr};
Automation<> *automation_{nullptr};
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
esphome>=2023.6.2
esphome==2023.7.1
14 changes: 7 additions & 7 deletions tests/esp32.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,49 +19,48 @@ switch:
id: lawn_sprinklers_mon
name: "Lawn sprinklers: Mon"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_tue
name: "Lawn sprinklers: Tue"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_wed
name: "Lawn sprinklers: Wed"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_thu
name: "Lawn sprinklers: Thu"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_fri
name: "Lawn sprinklers: Fri"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_sat
name: "Lawn sprinklers: Sat"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_sun
name: "Lawn sprinklers: Sun"
optimistic: true
restore_state: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
- platform: template
id: lawn_sprinklers_disabled
name: "Lawn sprinklers: Disable"
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config

Expand Down Expand Up @@ -105,6 +104,7 @@ dynamic_on_time:
fri: lawn_sprinklers_fri
sat: lawn_sprinklers_sat
sun: lawn_sprinklers_sun
disabled: lawn_sprinklers_disabled
on_time:
- logger.log:
format: 'schedule: Starting full sprinkler cycle'
Expand Down

0 comments on commit ad90ba6

Please sign in to comment.