From 5665f68a59162c16753e7182238d40eb1d4f7307 Mon Sep 17 00:00:00 2001 From: Ilia Sotnikov Date: Thu, 6 Jul 2023 23:06:28 +0300 Subject: [PATCH] Split `dynamic_on_time.h` into .h and .cpp --- .../dynamic_on_time/dynamic_on_time.cpp | 128 ++++++++++++++++++ components/dynamic_on_time/dynamic_on_time.h | 125 ++--------------- 2 files changed, 138 insertions(+), 115 deletions(-) create mode 100644 components/dynamic_on_time/dynamic_on_time.cpp diff --git a/components/dynamic_on_time/dynamic_on_time.cpp b/components/dynamic_on_time/dynamic_on_time.cpp new file mode 100644 index 0000000..624d260 --- /dev/null +++ b/components/dynamic_on_time/dynamic_on_time.cpp @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2023 Ilia Sotnikov + +#include "dynamic_on_time.h" // NOLINT(build/include_subdir) +#include "esphome/core/log.h" +#include "esphome/core/application.h" + +namespace esphome { +namespace dynamic_on_time { + +static const char *tag = "dynamic_on_time"; + +DynamicOnTime::DynamicOnTime( + time::RealTimeClock *rtc, + number::Number *hour, + number::Number *minute, + switch_::Switch *mon, + switch_::Switch *tue, + switch_::Switch *wed, + switch_::Switch *thu, + switch_::Switch *fri, + switch_::Switch *sat, + switch_::Switch *sun, + std::vector *> actions): + rtc_(rtc), + hour_(hour), minute_(minute), + mon_(mon), tue_(tue), wed_(wed), thu_(thu), fri_(fri), sat_(sat), + sun_(sun), actions_(actions) { + assert(this->hour_ != nullptr); + assert(this->minute_ != nullptr); + + for (number::Number *comp : {this->hour_, this->minute_}) { + comp->add_on_state_callback([this](float value) { this->setup(); }); + } + + assert(this->mon_ != nullptr); + assert(this->tue_ != nullptr); + assert(this->wed_ != nullptr); + assert(this->thu_ != nullptr); + assert(this->fri_ != nullptr); + assert(this->sat_ != nullptr); + assert(this->sun_ != nullptr); + + for (switch_::Switch *comp : { + this->mon_, this->tue_, this->wed_, this->thu_, this->fri_, this->sat_, + this->sun_ + }) { + comp->add_on_state_callback([this](float value) { this->setup(); }); + } +} + +std::vector DynamicOnTime::flags_to_days_of_week_( + bool mon, bool tue, bool wed, bool thu, bool fri, bool sat, bool sun +) { + std::vector days_of_week = { 1, 2, 3, 4, 5, 6, 7 }; + std::vector flags = { sun, mon, tue, wed, thu, fri, sat }; + + // https://en.cppreference.com/w/cpp/algorithm/remove, + // https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom + days_of_week.erase( + std::remove_if( + std::begin(days_of_week), std::end(days_of_week), + [&](uint8_t& arg) { return !flags[&arg - days_of_week.data()]; }), + days_of_week.end()); + + return days_of_week; +} + +void DynamicOnTime::setup() { + if (this->actions_.empty()) { + ESP_LOGW(tag, "No actions specified, exiting"); + return; + } + + bool to_register = false; + + assert(this->rtc_ != nullptr); + if (this->trigger_ != nullptr) { + // 'placement new', https://en.cppreference.com/w/cpp/language/new + this->trigger_->~CronTrigger(); + new (this->trigger_) time::CronTrigger(this->rtc_); + } else { + to_register = true; + this->trigger_ = new time::CronTrigger(this->rtc_); + } + + // Automation + if (this->automation_ != nullptr) + delete this->automation_; + + this->automation_ = new Automation<>(this->trigger_); + this->automation_->add_actions(this->actions_); + + this->trigger_->add_second(0); + for (uint8_t i = 1; i <= 31; i++) + this->trigger_->add_day_of_month(i); + for (uint8_t i = 1; i <= 12; i++) + this->trigger_->add_month(i); + + this->trigger_->add_hour(static_cast(this->hour_->state)); + this->trigger_->add_minute(static_cast(this->minute_->state)); + + std::vector days_of_week = this->flags_to_days_of_week_( + this->mon_->state, this->tue_->state, this->wed_->state, + this->thu_->state, this->fri_->state, this->sat_->state, + this->sun_->state); + this->trigger_->add_days_of_week(days_of_week); + + ESP_LOGCONFIG( + tag, "Cron trigger details (updated: %s)", + to_register ? "no": "yes"); + ESP_LOGCONFIG(tag, "Hour: %.0f", this->hour_->state); + ESP_LOGCONFIG(tag, "Minute: %.0f", this->minute_->state); + ESP_LOGCONFIG(tag, "Mon: %s", this->mon_->state ? "Yes": "No"); + ESP_LOGCONFIG(tag, "Tue: %s", this->tue_->state ? "Yes": "No"); + ESP_LOGCONFIG(tag, "Wed: %s", this->wed_->state ? "Yes": "No"); + ESP_LOGCONFIG(tag, "Thu: %s", this->thu_->state ? "Yes": "No"); + ESP_LOGCONFIG(tag, "Fri: %s", this->fri_->state ? "Yes": "No"); + ESP_LOGCONFIG(tag, "Sat: %s", this->sat_->state ? "Yes": "No"); + ESP_LOGCONFIG(tag, "Sun: %s", this->sun_->state ? "Yes": "No"); + + if (to_register) { + App.register_component(this->trigger_); + } +} + +} // namespace dynamic_on_time +} // namespace esphome diff --git a/components/dynamic_on_time/dynamic_on_time.h b/components/dynamic_on_time/dynamic_on_time.h index b222762..7469c6b 100644 --- a/components/dynamic_on_time/dynamic_on_time.h +++ b/components/dynamic_on_time/dynamic_on_time.h @@ -11,9 +11,16 @@ namespace esphome { namespace dynamic_on_time { -static const char *tag = "dynamic_on_time"; - class DynamicOnTime : public Component { + public: + explicit DynamicOnTime( + time::RealTimeClock *, number::Number *, number::Number *, + switch_::Switch *, switch_::Switch *, switch_::Switch *, switch_::Switch *, + switch_::Switch *, switch_::Switch *, switch_::Switch *, + std::vector *>); + + void setup() override; + protected: time::RealTimeClock *rtc_; number::Number *hour_; @@ -30,119 +37,7 @@ class DynamicOnTime : public Component { Automation<> *automation_{nullptr}; std::vector flags_to_days_of_week_( - bool mon, bool tue, bool wed, bool thu, bool fri, bool sat, bool sun - ) { - std::vector days_of_week = { 1, 2, 3, 4, 5, 6, 7 }; - std::vector flags = { sun, mon, tue, wed, thu, fri, sat }; - - // https://en.cppreference.com/w/cpp/algorithm/remove, - // https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom - days_of_week.erase( - std::remove_if( - std::begin(days_of_week), std::end(days_of_week), - [&](uint8_t& arg) { return !flags[&arg - days_of_week.data()]; }), - days_of_week.end()); - - return days_of_week; - } - - public: - DynamicOnTime( - time::RealTimeClock *rtc, - number::Number *hour, - number::Number *minute, - switch_::Switch *mon, - switch_::Switch *tue, - switch_::Switch *wed, - switch_::Switch *thu, - switch_::Switch *fri, - switch_::Switch *sat, - switch_::Switch *sun, - std::vector *> actions): - rtc_(rtc), - hour_(hour), minute_(minute), - mon_(mon), tue_(tue), wed_(wed), thu_(thu), fri_(fri), sat_(sat), - sun_(sun), actions_(actions) { - assert(this->hour_ != nullptr); - assert(this->minute_ != nullptr); - - for (number::Number *comp : {this->hour_, this->minute_}) { - comp->add_on_state_callback([this](float value) { this->setup(); }); - } - - assert(this->mon_ != nullptr); - assert(this->tue_ != nullptr); - assert(this->wed_ != nullptr); - assert(this->thu_ != nullptr); - assert(this->fri_ != nullptr); - assert(this->sat_ != nullptr); - assert(this->sun_ != nullptr); - - for (switch_::Switch *comp : { - this->mon_, this->tue_, this->wed_, this->thu_, this->fri_, this->sat_, - this->sun_ - }) { - comp->add_on_state_callback([this](float value) { this->setup(); }); - } - } - - void setup() override { - if (this->actions_.empty()) { - ESP_LOGW(tag, "No actions specified, exiting"); - return; - } - - bool to_register = false; - - assert(this->rtc_ != nullptr); - if (this->trigger_ != nullptr) { - // 'placement new', https://en.cppreference.com/w/cpp/language/new - this->trigger_->~CronTrigger(); - new (this->trigger_) time::CronTrigger(this->rtc_); - } else { - to_register = true; - this->trigger_ = new time::CronTrigger(this->rtc_); - } - - // Automation - if (this->automation_ != nullptr) - delete this->automation_; - - this->automation_ = new Automation<>(this->trigger_); - this->automation_->add_actions(this->actions_); - - this->trigger_->add_second(0); - for (uint8_t i = 1; i <= 31; i++) - this->trigger_->add_day_of_month(i); - for (uint8_t i = 1; i <= 12; i++) - this->trigger_->add_month(i); - - this->trigger_->add_hour(static_cast(this->hour_->state)); - this->trigger_->add_minute(static_cast(this->minute_->state)); - - std::vector days_of_week = this->flags_to_days_of_week_( - this->mon_->state, this->tue_->state, this->wed_->state, - this->thu_->state, this->fri_->state, this->sat_->state, - this->sun_->state); - this->trigger_->add_days_of_week(days_of_week); - - ESP_LOGCONFIG( - tag, "Cron trigger details (updated: %s)", - to_register ? "no": "yes"); - ESP_LOGCONFIG(tag, "Hour: %.0f", this->hour_->state); - ESP_LOGCONFIG(tag, "Minute: %.0f", this->minute_->state); - ESP_LOGCONFIG(tag, "Mon: %s", this->mon_->state ? "Yes": "No"); - ESP_LOGCONFIG(tag, "Tue: %s", this->tue_->state ? "Yes": "No"); - ESP_LOGCONFIG(tag, "Wed: %s", this->wed_->state ? "Yes": "No"); - ESP_LOGCONFIG(tag, "Thu: %s", this->thu_->state ? "Yes": "No"); - ESP_LOGCONFIG(tag, "Fri: %s", this->fri_->state ? "Yes": "No"); - ESP_LOGCONFIG(tag, "Sat: %s", this->sat_->state ? "Yes": "No"); - ESP_LOGCONFIG(tag, "Sun: %s", this->sun_->state ? "Yes": "No"); - - if (to_register) { - App.register_component(this->trigger_); - } - } + bool, bool, bool, bool, bool, bool, bool); }; } // namespace dynamic_on_time