13static const char *
const TAG =
"sprinkler";
18 : pulse_duration_(pulse_duration), off_switch_(off_switch), on_switch_(on_switch) {}
73 this->
state_ = latch_state;
108 : turn_on_trigger_(new
Trigger<>()), turn_off_trigger_(new
Trigger<>()) {}
111 if (!this->
f_.has_value())
113 auto s = (*this->
f_)();
148 : controller_(controller), valve_(valve) {}
181 if (controller !=
nullptr) {
187 if (valve !=
nullptr) {
270 if (completed_millis >
millis()) {
271 return (completed_millis -
millis()) / 1000;
317 if (this->
valve_ ==
nullptr) {
326 if (this->
valve_ ==
nullptr) {
349 : valve_number_(valve_number), run_duration_(run_duration), valve_op_(valve_op) {}
366 if (valve_op !=
nullptr) {
405 for (
auto &p : this->
pump_) {
408 for (
auto &v : this->
valve_) {
409 v.valve_switch.loop();
421 this->
valve_.resize(new_valve_number + 1);
442 if (enable_sw !=
nullptr) {
452 for (
size_t valve_number = 0; valve_number < this->
number_of_valves(); valve_number++) {
453 if (this->
valve_[valve_number].controller_switch->
state) {
500 this->
valve_[valve_number].run_duration = run_duration;
506 uint32_t run_duration) {
508 this->
valve_[valve_number].valve_switch.set_off_switch(valve_switch_off);
509 this->
valve_[valve_number].valve_switch.set_on_switch(valve_switch_on);
510 this->
valve_[valve_number].valve_switch.set_pulse_duration(pulse_duration);
511 this->
valve_[valve_number].run_duration = run_duration;
517 for (
size_t i = 0; i < this->
pump_.size(); i++) {
518 if (this->
pump_[i].on_switch() == pump_switch) {
519 this->
valve_[valve_number].pump_switch_index = i;
524 this->
pump_.back().set_on_switch(pump_switch);
525 this->
valve_[valve_number].pump_switch_index = this->
pump_.size() - 1;
532 for (
size_t i = 0; i < this->
pump_.size(); i++) {
533 if ((this->
pump_[i].off_switch() == pump_switch_off) &&
534 (this->
pump_[i].on_switch() == pump_switch_on)) {
535 this->
valve_[valve_number].pump_switch_index = i;
540 this->
pump_.back().set_off_switch(pump_switch_off);
541 this->
pump_.back().set_on_switch(pump_switch_on);
542 this->
pump_.back().set_pulse_duration(pulse_duration);
543 this->
valve_[valve_number].pump_switch_index = this->
pump_.size() - 1;
550 this->
valve_[valve_number].run_duration_number = run_duration_number;
558 if (divider.
value() > 0) {
561 }
else if (divider.
value() == 0) {
612 if (valve_open_delay > 0) {
621 if (valve_overlap > 0) {
631 if (manual_selection_delay > 0) {
646 if (this->
valve_[valve_number.
value()].run_duration_number ==
nullptr) {
649 if (this->
valve_[valve_number.
value()].run_duration_number->state == run_duration.
value()) {
652 auto call = this->
valve_[valve_number.
value()].run_duration_number->make_call();
653 if (this->
valve_[valve_number.
value()].run_duration_number->traits.get_unit_of_measurement() ==
MIN_STR) {
654 call.set_value(run_duration.
value() / 60.0);
734 if (this->
valve_[valve_number].run_duration_number !=
nullptr) {
735 if (this->
valve_[valve_number].run_duration_number->traits.get_unit_of_measurement() ==
MIN_STR) {
736 return static_cast<uint32_t
>(roundf(this->
valve_[valve_number].run_duration_number->state * 60));
738 return static_cast<uint32_t
>(roundf(this->
valve_[valve_number].run_duration_number->state));
741 return this->
valve_[valve_number].run_duration;
745 uint32_t run_duration = 0;
750 run_duration =
static_cast<uint32_t
>(roundf(run_duration * this->
multiplier()));
811 ESP_LOGD(TAG,
"start_from_queue called but standby is enabled; no action taken");
815 ESP_LOGD(TAG,
"start_from_queue called but multiplier is set to zero; no action taken");
835 ESP_LOGD(TAG,
"start_full_cycle called but standby is enabled; no action taken");
839 ESP_LOGD(TAG,
"start_full_cycle called but multiplier is set to zero; no action taken");
858 ESP_LOGD(TAG,
"start_single_valve called but standby is enabled; no action taken");
862 ESP_LOGD(TAG,
"start_single_valve called but multiplier is set to zero; no action taken");
865 if (!valve_number.
has_value() || (valve_number == this->active_valve())) {
879 if (this->
is_a_valid_valve(valve_number.
value()) && (this->queued_valves_.size() < this->max_queue_size_)) {
882 ESP_LOGD(TAG,
"Valve %zu placed into queue with run duration of %" PRIu32
" seconds", valve_number.
value_or(0),
890 ESP_LOGD(TAG,
"Queue cleared");
899 this->
manual_valve_.
value_or(this->active_req_.valve_as_opt().value_or(this->number_of_valves() - 1)),
900 !this->next_prev_ignore_disabled_,
true);
903 ESP_LOGD(TAG,
"next_valve was called but no valve could be started; perhaps next_prev_ignore_disabled allows only "
904 "enabled valves and no valves are enabled?");
923 !this->next_prev_ignore_disabled_,
true);
926 ESP_LOGD(TAG,
"previous_valve was called but no valve could be started; perhaps next_prev_ignore_disabled allows "
927 "only enabled valves and no valves are enabled?");
961 ESP_LOGD(TAG,
"Paused valve %zu with %" PRIu32
" seconds remaining", this->
paused_valve_.
value_or(0),
962 this->resume_duration_.value_or(0));
967 ESP_LOGD(TAG,
"resume called but standby is enabled; no action taken");
974 ESP_LOGD(TAG,
"Resuming valve %zu with %" PRIu32
" seconds remaining", this->
paused_valve_.
value_or(0),
975 this->resume_duration_.value_or(0));
980 ESP_LOGD(TAG,
"No valve to resume!");
999 return this->
valve_[valve_number].controller_switch->get_name().c_str();
1013 (this->prev_req_.valve_operator()->state() ==
STARTING || this->prev_req_.valve_operator()->state() ==
ACTIVE)) {
1037 if (pump_switch ==
nullptr) {
1047 if ((vo.state() !=
BYPASS) && (vo.pump_switch() !=
nullptr)) {
1049 if ((vo.pump_switch()->off_switch() == pump_switch->
off_switch()) &&
1050 (vo.pump_switch()->on_switch() == pump_switch->
on_switch())) {
1053 if ((vo.state() ==
ACTIVE) ||
1054 ((vo.state() ==
STARTING) && this->start_delay_ && this->start_delay_is_valve_delay_) ||
1055 ((vo.state() ==
STOPPING) && this->stop_delay_ && this->stop_delay_is_valve_delay_)) {
1062 this->active_req_.has_request() && (this->state_ !=
STOPPING)) {
1065 return (pump_switch->
off_switch() == this->valve_pump_switch(this->active_req_.valve())->off_switch()) &&
1072 if (pump_switch ==
nullptr) {
1076 bool hold_pump_on =
false;
1079 if (controller !=
this) {
1080 if (controller->pump_in_use(pump_switch)) {
1081 hold_pump_on =
true;
1091 ESP_LOGD(TAG,
"Leaving pump on because another controller instance is using it");
1096 }
else if (!hold_pump_on && !this->
pump_in_use(pump_switch)) {
1098 }
else if (hold_pump_on) {
1104 uint32_t total_time_remaining = 0;
1116 return total_time_remaining;
1120 uint32_t total_time_remaining = 0;
1121 uint32_t valve_count = 0;
1138 return total_time_remaining;
1142 uint32_t total_time_remaining = 0;
1143 uint32_t enabled_valve_count = 0;
1144 uint32_t incomplete_valve_count = 0;
1148 enabled_valve_count++;
1152 incomplete_valve_count++;
1157 incomplete_valve_count++;
1164 if (incomplete_valve_count >= enabled_valve_count) {
1165 incomplete_valve_count--;
1167 if (incomplete_valve_count) {
1175 return total_time_remaining;
1179 uint32_t total_time_remaining = 0;
1180 uint32_t valve_count = 0;
1183 if (valve.run_duration) {
1184 total_time_remaining += valve.run_duration;
1199 return total_time_remaining;
1224 if (this->
repeat().value_or(0) > 0) {
1225 total_time_remaining +=
1233 return total_time_remaining;
1242 if (controller !=
this) {
1243 if (controller->controller_state() !=
IDLE) {
1253 return this->
valve_[valve_number].controller_switch;
1260 return this->
valve_[valve_number].enable_switch;
1267 return &this->
valve_[valve_number].valve_switch;
1274 return &this->
pump_[this->
valve_[valve_number].pump_switch_index.value()];
1280 if (pump_index < this->
pump_.size()) {
1281 return &this->
pump_[pump_index];
1289 return this->
valve_[valve_number].enable_switch->state;
1299 ESP_LOGD(TAG,
"Marking valve %u complete", valve_number);
1300 this->
valve_[valve_number].valve_cycle_complete =
true;
1306 return this->
valve_[valve_number].valve_cycle_complete;
1312 const bool include_complete) {
1313 auto valve = first_valve.
value_or(0);
1314 size_t start = first_valve.
has_value() ? 1 : 0;
1321 auto valve_of_interest = valve + offset;
1328 return valve_of_interest;
1335 const bool include_complete) {
1337 size_t start = first_valve.
has_value() ? 1 : 0;
1344 auto valve_of_interest = valve - offset;
1351 return valve_of_interest;
1396 ESP_LOGD(TAG,
"Repeating - starting cycle %" PRIu32
" of %" PRIu32, this->
repeat_count_ + 1,
1397 this->
repeat().value_or(0) + 1);
1411 for (
size_t valve_number = 0; valve_number < this->
number_of_valves(); valve_number++) {
1426 if (vo.state() ==
IDLE) {
1428 ESP_LOGD(TAG,
"%s is starting valve %zu for %" PRIu32
" seconds, cycle %" PRIu32
" of %" PRIu32,
1430 this->repeat().value_or(0) + 1);
1432 vo.set_controller(
this);
1434 vo.set_run_duration(run_duration);
1444 for (
size_t valve_index = 0; valve_index < this->
number_of_valves(); valve_index++) {
1446 this->
valve_[valve_index].valve_switch.turn_off();
1452 ESP_LOGD(TAG,
"All valves stopped%s", include_pump ?
", including pumps" :
"");
1459 for (
auto &valve : this->
valve_) {
1460 if (valve.enable_switch !=
nullptr) {
1461 if (!valve.enable_switch->state) {
1462 valve.enable_switch->turn_on();
1471 for (
auto &valve : this->
valve_) {
1472 valve.valve_cycle_complete =
false;
1491 ESP_LOGVV(TAG,
"fsm_transition_ called; state is %s", this->
state_as_str_(this->
state_).c_str());
1534 ESP_LOGVV(TAG,
"fsm_transition_ complete; new state is %s", this->
state_as_str_(this->
state_).c_str());
1565 ESP_LOGD(TAG,
"Valve cycle interrupted - NOT flagging valve as complete and stopping current valve");
1592 (this->pump_switch_off_during_valve_open_delay_ && same_pump ? this->stop_delay_ : 0));
1651 this->
timer_[timer_index].active =
true;
1653 ESP_LOGVV(TAG,
"Timer %zu started for %" PRIu32
" sec",
static_cast<size_t>(timer_index),
1658 this->
timer_[timer_index].active =
false;
1665 this->
timer_[timer_index].time = 1000 * time;
1671 return this->
timer_[timer_index].func;
1676 ESP_LOGVV(TAG,
"Valve selection timer expired");
1685 ESP_LOGVV(TAG,
"State machine timer expired");
1690 ESP_LOGCONFIG(TAG,
"Sprinkler Controller -- %s", this->
name_.c_str());
1694 if (this->
repeat().has_value()) {
1695 ESP_LOGCONFIG(TAG,
" Repeat Cycles: %" PRIu32
" times", this->
repeat().value_or(0));
1699 ESP_LOGCONFIG(TAG,
" Pump Start Valve Delay: %" PRIu32
" seconds", this->
start_delay_);
1701 ESP_LOGCONFIG(TAG,
" Pump Start Pump Delay: %" PRIu32
" seconds", this->
start_delay_);
1706 ESP_LOGCONFIG(TAG,
" Pump Stop Valve Delay: %" PRIu32
" seconds", this->
stop_delay_);
1708 ESP_LOGCONFIG(TAG,
" Pump Stop Pump Delay: %" PRIu32
" seconds", this->
stop_delay_);
1716 ESP_LOGCONFIG(TAG,
" Pump Switch Off During Valve Open Delay: %s",
1720 for (
size_t valve_number = 0; valve_number < this->
number_of_valves(); valve_number++) {
1721 ESP_LOGCONFIG(TAG,
" Valve %zu:", valve_number);
1722 ESP_LOGCONFIG(TAG,
" Name: %s", this->
valve_name(valve_number));
1723 ESP_LOGCONFIG(TAG,
" Run Duration: %" PRIu32
" seconds", this->
valve_run_duration(valve_number));
1725 ESP_LOGCONFIG(TAG,
" Pulse Duration: %" PRIu32
" milliseconds",
1729 if (!this->
pump_.empty()) {
1730 ESP_LOGCONFIG(TAG,
" Total number of pumps: %zu", this->
pump_.size());
1732 if (!this->
valve_.empty()) {
1733 ESP_LOGCONFIG(TAG,
" Total number of valves: %zu", this->
valve_.size());
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
bool cancel_timeout(const std::string &name)
Cancel a timeout function.
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
uint32_t get_object_id_hash()
void stop_action()
Stop any action connected to this trigger.
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
NumberCall & set_value(float value)
void publish_state(float state)
float get_min_value() const
value_type value_or(U const &v) const
value_type const & value() const
Trigger< float > * set_trigger_
void dump_config() override
ESPPreferenceObject pref_
void control(float value) override
Trigger * turn_off_trigger_
SprinklerControllerSwitch()
float get_setup_priority() const override
void dump_config() override
Trigger * turn_on_trigger_
void set_state_lambda(std::function< optional< bool >()> &&f)
void write_state(bool state) override
optional< std::function< optional< bool >()> > f_
Trigger * get_turn_off_trigger() const
Trigger * get_turn_on_trigger() const
void set_controller_standby_switch(SprinklerControllerSwitch *standby_switch)
void add_controller(Sprinkler *other_controller)
add another controller to the controller so it can check if pumps/main valves are in use
void resume()
resumes a cycle that was suspended using pause()
bool pump_in_use(SprinklerSwitch *pump_switch)
returns true if the pump the pointer points to is in use
SprinklerSwitch * valve_pump_switch(size_t valve_number)
returns a pointer to a valve's pump switch object
void fsm_transition_to_shutdown_()
starts up the system from IDLE state
optional< size_t > previous_valve_number_(optional< size_t > first_valve=nullopt, bool include_disabled=true, bool include_complete=true)
returns the number of the previous valve in the vector or nullopt if no valves match criteria
bool is_a_valid_valve(size_t valve_number)
returns true if valve number is valid
bool reverse()
returns true if reverse is enabled
bool next_prev_ignore_disabled_
When set to true, the next and previous actions will skip disabled valves.
void reset_resume()
resets resume state
SprinklerControllerNumber * repeat_number_
bool valve_is_enabled_(size_t valve_number)
returns true if valve number is enabled
SprinklerState state_
Sprinkler controller state.
void next_valve()
advances to the next valve (numerically)
std::vector< SprinklerSwitch > pump_
Sprinkler valve pump objects.
uint32_t repeat_count_
Number of times the full cycle has been repeated.
void configure_valve_switch(size_t valve_number, switch_::Switch *valve_switch, uint32_t run_duration)
configure a valve's switch object and run duration. run_duration is time in seconds.
std::vector< SprinklerValve > valve_
Sprinkler valve objects.
void queue_valve(optional< size_t > valve_number, optional< uint32_t > run_duration)
adds a valve into the queue.
bool stop_delay_is_valve_delay_
void set_valve_run_duration(optional< size_t > valve_number, optional< uint32_t > run_duration)
set how long the valve should remain on/open. run_duration is time in seconds
optional< uint32_t > resume_duration_
Set from time_remaining() when paused.
void set_repeat(optional< uint32_t > repeat)
set the number of times to repeat a full cycle
float multiplier()
returns the current value of the multiplier
bool auto_advance()
returns true if auto_advance is enabled
uint32_t total_queue_time()
returns the amount of time in seconds required for all valves in the queue
void fsm_transition_from_shutdown_()
starts up the system from IDLE state
optional< uint32_t > repeat_count()
if a cycle is active, returns the number of times the controller has repeated the cycle....
void all_valves_off_(bool include_pump=false)
turns off/closes all valves, including pump if include_pump is true
SprinklerValveRunRequest prev_req_
The previous run request the controller processed.
void start_valve_(SprinklerValveRunRequest *req)
loads an available SprinklerValveOperator (valve_op_) based on req and starts it (switches it on).
optional< uint32_t > repeat()
returns the number of times the controller is set to repeat cycles, if at all. check with 'has_value(...
void mark_valve_cycle_complete_(size_t valve_number)
marks a valve's cycle as complete
void set_pump_stop_delay(uint32_t stop_delay)
set how long the pump should stop after the valve (when the pump is starting)
optional< size_t > paused_valve()
returns the number of the valve that is paused, if any. check with 'has_value()'
void set_controller_reverse_switch(SprinklerControllerSwitch *reverse_switch)
uint32_t start_delay_
Pump start/stop delay intervals.
void set_valve_overlap(uint32_t valve_overlap)
set how long the controller should wait after opening a valve before closing the previous valve
optional< SprinklerValveRunRequestOrigin > active_valve_request_is_from()
returns what invoked the valve that is currently active, if any. check with 'has_value()'
void set_reverse(bool reverse)
if reverse is true, controller will iterate through all enabled valves in reverse (descending) order
SprinklerControllerNumber * multiplier_number_
Number components we'll present to the front end.
std::vector< SprinklerValveOperator > valve_op_
Sprinkler valve operator objects.
SprinklerControllerSwitch * enable_switch(size_t valve_number)
returns a pointer to a valve's enable switch object
void start_full_cycle()
starts a full cycle of all enabled valves and enables auto_advance.
std::string req_as_str_(SprinklerValveRunRequestOrigin origin)
return the specified SprinklerValveRunRequestOrigin as a string
std::vector< SprinklerTimer > timer_
Valve control timers.
SprinklerControllerSwitch * controller_sw_
void set_valve_stop_delay(uint32_t stop_delay)
set how long the valve should stop after the pump (when the pump is stopping)
void set_controller_queue_enable_switch(SprinklerControllerSwitch *queue_enable_switch)
std::string state_as_str_(SprinklerState state)
return the specified SprinklerState state as a string
optional< uint32_t > target_repeats_
Set the number of times to repeat a full cycle.
void set_controller_main_switch(SprinklerControllerSwitch *controller_switch)
configure important controller switches
optional< uint32_t > time_remaining_current_operation()
returns the amount of time remaining in seconds for all valves remaining, including the active valve,...
SprinklerControllerSwitch * reverse_sw_
optional< uint32_t > switching_delay_
Valve switching delay.
void fsm_kick_()
kicks the state machine to advance, starting it if it is not already active
void shutdown(bool clear_queue=false)
turns off all valves, effectively shutting down the system.
SprinklerValveRunRequest active_req_
The valve run request that is currently active.
bool any_controller_is_active()
returns true if this or any sprinkler controller this controller knows about is active
void set_valve_open_delay(uint32_t valve_open_delay)
set how long the controller should wait to open/switch on the valve after it becomes active
bool start_delay_is_valve_delay_
Pump start/stop delay interval types.
optional< size_t > manual_valve_
The number of the manually selected valve currently selected.
bool pump_switch_off_during_valve_open_delay_
Pump should be off during valve_open_delay interval.
bool cancel_timer_(SprinklerTimerIndex timer_index)
SprinklerControllerSwitch * queue_enable_sw_
void start_timer_(SprinklerTimerIndex timer_index)
Start/cancel/get status of valve timers.
void previous_valve()
advances to the previous valve (numerically)
void set_auto_advance(bool auto_advance)
if auto_advance is true, controller will iterate through all enabled valves
void prep_full_cycle_()
prepares for a full cycle by verifying auto-advance is on as well as one or more valve enable switche...
uint32_t valve_run_duration_adjusted(size_t valve_number)
returns valve_number's run duration (in seconds) adjusted by multiplier_
std::unique_ptr< ShutdownAction<> > sprinkler_shutdown_action_
std::unique_ptr< ResumeOrStartAction<> > sprinkler_resumeorstart_action_
void clear_queued_valves()
clears/removes all valves from the queue
bool any_valve_is_enabled_()
returns true if any valve is enabled
SprinklerSwitch * valve_pump_switch_by_pump_index(size_t pump_index)
returns a pointer to a valve's pump switch object
size_t number_of_valves()
returns the number of valves the controller is configured with
void set_pump_start_delay(uint32_t start_delay)
set how long the pump should start after the valve (when the pump is starting)
void set_standby(bool standby)
if standby is true, controller will refuse to activate any valves
std::vector< SprinklerQueueItem > queued_valves_
Queue of valves to activate next, regardless of auto-advance.
bool queue_enabled()
returns true if the queue is enabled to run
void dump_config() override
void resume_or_start_full_cycle()
if a cycle was suspended using pause(), resumes it. otherwise calls start_full_cycle()
std::unique_ptr< Automation<> > sprinkler_turn_on_automation_
void sm_timer_callback_()
void valve_selection_callback_()
callback functions for timers
optional< size_t > next_valve_number_(optional< size_t > first_valve=nullopt, bool include_disabled=true, bool include_complete=true)
returns the number of the next valve in the vector or nullopt if no valves match criteria
SprinklerSwitch * valve_switch(size_t valve_number)
returns a pointer to a valve's switch object
uint32_t total_cycle_time_all_valves()
returns the amount of time in seconds required for all valves
std::unique_ptr< Automation<> > sprinkler_turn_off_automation_
optional< uint32_t > time_remaining_active_valve()
returns the amount of time remaining in seconds for the active valve, if any
optional< size_t > next_valve_number_in_cycle_(optional< size_t > first_valve=nullopt)
returns the number of the next valve that should be activated in a full cycle.
std::function< void()> timer_cbf_(SprinklerTimerIndex timer_index)
void set_pump_switch_off_during_valve_open_delay(bool pump_switch_off_during_valve_open_delay)
if pump_switch_off_during_valve_open_delay is true, the controller will switch off the pump during th...
std::unique_ptr< ShutdownAction<> > sprinkler_standby_shutdown_action_
optional< uint32_t > manual_selection_delay_
Manual switching delay.
void set_controller_repeat_number(SprinklerControllerNumber *repeat_number)
void start_single_valve(optional< size_t > valve_number, optional< uint32_t > run_duration=nullopt)
activates a single valve and disables auto_advance.
uint32_t valve_run_duration(size_t valve_number)
returns valve_number's run duration in seconds
void load_next_valve_run_request_(optional< size_t > first_valve=nullopt)
loads next_req_ with the next valve that should be activated, including its run duration.
void fsm_transition_()
advance controller state, advancing to target_valve if provided
void fsm_request_(size_t requested_valve, uint32_t requested_run_duration=0)
make a request of the state machine
optional< size_t > paused_valve_
The number of the valve to resume from (if paused)
SprinklerValveRunRequest next_req_
The next run request for the controller to consume after active_req_ is complete.
void configure_valve_run_duration_number(size_t valve_number, SprinklerControllerNumber *run_duration_number)
configure a valve's run duration number component
SprinklerControllerSwitch * auto_adv_sw_
Switches we'll present to the front end.
void set_controller_multiplier_number(SprinklerControllerNumber *multiplier_number)
configure important controller number components
void set_manual_selection_delay(uint32_t manual_selection_delay)
set how long the controller should wait to activate a valve after next_valve() or previous_valve() is...
uint32_t total_cycle_time_enabled_incomplete_valves()
returns the amount of time in seconds required for all enabled & incomplete valves,...
bool valve_overlap_
Sprinkler valve cycle should overlap.
void configure_valve_pump_switch_pulsed(size_t valve_number, switch_::Switch *pump_switch_off, switch_::Switch *pump_switch_on, uint32_t pulse_duration)
void set_divider(optional< uint32_t > divider)
sets the multiplier value to '1 / divider' and sets repeat value to divider
std::unique_ptr< Automation<> > sprinkler_standby_turn_on_automation_
void set_valve_start_delay(uint32_t start_delay)
set how long the valve should start after the pump (when the pump is stopping)
void pause()
same as shutdown(), but also stores active_valve() and time_remaining() allowing resume() to continue...
void set_next_prev_ignore_disabled_valves(bool ignore_disabled)
enable/disable skipping of disabled valves by the next and previous actions
optional< size_t > active_valve()
returns the number of the valve that is currently active, if any. check with 'has_value()'
void set_queue_enable(bool queue_enable)
if queue_enable is true, controller will iterate through valves in the queue
bool timer_active_(SprinklerTimerIndex timer_index)
returns true if the specified timer is active/running
optional< size_t > queued_valve()
returns the number of the next valve in the queue, if any. check with 'has_value()'
void set_pump_state(SprinklerSwitch *pump_switch, bool state)
switches on/off a pump "safely" by checking that the new state will not conflict with another control...
std::vector< Sprinkler * > other_controllers_
Other Sprinkler instances we should be aware of (used to check if pumps are in use)
const char * valve_name(size_t valve_number)
returns a pointer to a valve's name string object; returns nullptr if valve_number is invalid
void start_from_queue()
starts the controller from the first valve in the queue and disables auto_advance.
void configure_valve_pump_switch(size_t valve_number, switch_::Switch *pump_switch)
configure a valve's associated pump switch object
void reset_cycle_states_()
resets the cycle state for all valves
float multiplier_
Sprinkler valve run time multiplier value.
SprinklerControllerSwitch * control_switch(size_t valve_number)
returns a pointer to a valve's control switch object
void set_multiplier(optional< float > multiplier)
value multiplied by configured run times – used to extend or shorten the cycle
void set_timer_duration_(SprinklerTimerIndex timer_index, uint32_t time)
time is converted to milliseconds (ms) for set_timeout()
void set_controller_auto_adv_switch(SprinklerControllerSwitch *auto_adv_switch)
void fsm_transition_from_valve_run_()
transitions from ACTIVE state to ACTIVE (as in, next valve) or to a SHUTDOWN or IDLE state
bool standby()
returns true if standby is enabled
uint32_t total_cycle_time_enabled_valves()
returns the amount of time in seconds required for all enabled valves
bool valve_cycle_complete_(size_t valve_number)
returns true if valve's cycle is flagged as complete
optional< size_t > manual_valve()
returns the number of the valve that is manually selected, if any.
void add_valve(SprinklerControllerSwitch *valve_sw, SprinklerControllerSwitch *enable_sw=nullptr)
add a valve to the controller
SprinklerControllerSwitch * standby_sw_
uint32_t timer_duration_(SprinklerTimerIndex timer_index)
returns time in milliseconds (ms)
void configure_valve_switch_pulsed(size_t valve_number, switch_::Switch *valve_switch_off, switch_::Switch *valve_switch_on, uint32_t pulse_duration, uint32_t run_duration)
switch_::Switch * on_switch_
switch_::Switch * on_switch()
void sync_valve_state(bool latch_state)
switch_::Switch * off_switch()
switch_::Switch * off_switch_
uint32_t pulse_duration()
bool stop_delay_is_valve_delay_
void set_valve(SprinklerValve *valve)
void set_run_duration(uint32_t run_duration)
uint32_t time_remaining()
bool start_delay_is_valve_delay_
void set_start_delay(uint32_t start_delay, bool start_delay_is_valve_delay)
void set_controller(Sprinkler *controller)
void set_stop_delay(uint32_t stop_delay, bool stop_delay_is_valve_delay)
SprinklerSwitch * pump_switch()
SprinklerValveRunRequestOrigin origin_
SprinklerValveRunRequestOrigin request_is_from()
void set_request_from(SprinklerValveRunRequestOrigin origin)
SprinklerValveOperator * valve_op_
SprinklerValveOperator * valve_operator()
void set_valve(size_t valve_number)
void set_run_duration(uint32_t run_duration)
optional< size_t > valve_as_opt()
SprinklerValveRunRequest()
void set_valve_operator(SprinklerValveOperator *valve_op)
bool has_valve_operator()
Base class for all switches.
void turn_on()
Turn this switch on.
void turn_off()
Turn this switch off.
bool state
The current reported state of the binary sensor.
void publish_state(bool state)
Publish a state to the front-end from the back-end.
optional< bool > get_initial_state_with_restore_mode()
Returns the initial state of the switch, after applying restore mode rules.
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
SprinklerValveRunRequestOrigin
const std::string MIN_STR
Providing packet encoding functions for exchanging data with a remote host.
ESPPreferences * global_preferences
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.
const nullopt_t nullopt((nullopt_t::init()))
std::unique_ptr< StartSingleValveAction<> > valve_resumeorstart_action
std::unique_ptr< Automation<> > valve_turn_off_automation
SprinklerControllerSwitch * enable_switch
std::unique_ptr< ShutdownAction<> > valve_shutdown_action
SprinklerControllerSwitch * controller_switch
SprinklerSwitch valve_switch
std::unique_ptr< Automation<> > valve_turn_on_automation
optional< size_t > pump_switch_index