ESPHome  2024.12.2
sprinkler.h
Go to the documentation of this file.
1 #pragma once
2 
5 #include "esphome/core/hal.h"
8 
9 #include <vector>
10 
11 namespace esphome {
12 namespace sprinkler {
13 
14 const std::string MIN_STR = "min";
15 
16 enum SprinklerState : uint8_t {
17  // NOTE: these states are used by both SprinklerValveOperator and Sprinkler (the controller)!
18  IDLE, // system/valve is off
19  STARTING, // system/valve is starting/"half open" -- either pump or valve is on, but the remaining pump/valve is not
20  ACTIVE, // system/valve is running its cycle
21  STOPPING, // system/valve is stopping/"half open" -- either pump or valve is on, but the remaining pump/valve is not
22  BYPASS // used by SprinklerValveOperator to ignore the instance checking pump status
23 };
24 
25 enum SprinklerTimerIndex : uint8_t {
26  TIMER_SM = 0,
28 };
29 
34 };
35 
36 class Sprinkler; // this component
37 class SprinklerControllerNumber; // number components that appear in the front end; based on number core
38 class SprinklerControllerSwitch; // switches that appear in the front end; based on switch core
39 class SprinklerSwitch; // switches representing any valve or pump; provides abstraction for latching valves
40 class SprinklerValveOperator; // manages all switching on/off of valves and associated pumps
41 class SprinklerValveRunRequest; // tells the sprinkler controller what valve to run and for how long as well as what
42  // SprinklerValveOperator is handling it
43 template<typename... Ts> class StartSingleValveAction;
44 template<typename... Ts> class ShutdownAction;
45 template<typename... Ts> class ResumeOrStartAction;
46 
48  public:
50  SprinklerSwitch(switch_::Switch *sprinkler_switch);
52 
53  bool is_latching_valve(); // returns true if configured as a latching valve
54  void loop(); // called as a part of loop(), used for latching valve pulses
55  uint32_t pulse_duration() { return this->pulse_duration_; }
56  bool state(); // returns the switch's current state
57  void set_off_switch(switch_::Switch *off_switch) { this->off_switch_ = off_switch; }
58  void set_on_switch(switch_::Switch *on_switch) { this->on_switch_ = on_switch; }
59  void set_pulse_duration(uint32_t pulse_duration) { this->pulse_duration_ = pulse_duration; }
60  void sync_valve_state(
61  bool latch_state); // syncs internal state to switch; if latching valve, sets state to latch_state
62  void turn_off(); // sets internal flag and actuates the switch
63  void turn_on(); // sets internal flag and actuates the switch
64  switch_::Switch *off_switch() { return this->off_switch_; }
65  switch_::Switch *on_switch() { return this->on_switch_; }
66 
67  protected:
68  bool state_{false};
69  uint32_t pulse_duration_{0};
70  uint64_t pinned_millis_{0};
71  switch_::Switch *off_switch_{nullptr}; // only used for latching valves
72  switch_::Switch *on_switch_{nullptr}; // used for both latching and non-latching valves
73 };
74 
76  size_t valve_number;
77  uint32_t run_duration;
78 };
79 
81  const std::string name;
82  bool active;
83  uint32_t time;
84  uint32_t start_time;
85  std::function<void()> func;
86 };
87 
93  uint32_t run_duration;
96  std::unique_ptr<ShutdownAction<>> valve_shutdown_action;
97  std::unique_ptr<StartSingleValveAction<>> valve_resumeorstart_action;
98  std::unique_ptr<Automation<>> valve_turn_off_automation;
99  std::unique_ptr<Automation<>> valve_turn_on_automation;
100 };
101 
103  public:
104  void setup() override;
105  void dump_config() override;
106  float get_setup_priority() const override { return setup_priority::PROCESSOR; }
107 
108  Trigger<float> *get_set_trigger() const { return set_trigger_; }
109  void set_initial_value(float initial_value) { initial_value_ = initial_value; }
110  void set_restore_value(bool restore_value) { this->restore_value_ = restore_value; }
111 
112  protected:
113  void control(float value) override;
114  float initial_value_{NAN};
115  bool restore_value_{true};
116  Trigger<float> *set_trigger_ = new Trigger<float>();
117 
119 };
120 
122  public:
124 
125  void setup() override;
126  void dump_config() override;
127 
128  void set_state_lambda(std::function<optional<bool>()> &&f);
129  Trigger<> *get_turn_on_trigger() const;
130  Trigger<> *get_turn_off_trigger() const;
131  void loop() override;
132 
133  float get_setup_priority() const override;
134 
135  protected:
136  void write_state(bool state) override;
137 
141  Trigger<> *prev_trigger_{nullptr};
142 };
143 
145  public:
147  SprinklerValveOperator(SprinklerValve *valve, Sprinkler *controller);
148  void loop();
149  void set_controller(Sprinkler *controller);
150  void set_valve(SprinklerValve *valve);
151  void set_run_duration(uint32_t run_duration); // set the desired run duration in seconds
152  void set_start_delay(uint32_t start_delay, bool start_delay_is_valve_delay);
153  void set_stop_delay(uint32_t stop_delay, bool stop_delay_is_valve_delay);
154  void start();
155  void stop();
156  uint32_t run_duration(); // returns the desired run duration in seconds
157  uint32_t time_remaining(); // returns seconds remaining (does not include stop_delay_)
158  SprinklerState state(); // returns the valve's state/status
159  SprinklerSwitch *pump_switch(); // returns this SprinklerValveOperator's pump's SprinklerSwitch
160 
161  protected:
162  void pump_off_();
163  void pump_on_();
164  void valve_off_();
165  void valve_on_();
166  void kill_();
167  void run_();
168  bool start_delay_is_valve_delay_{false};
169  bool stop_delay_is_valve_delay_{false};
170  uint32_t start_delay_{0};
171  uint32_t stop_delay_{0};
172  uint32_t run_duration_{0};
173  uint64_t start_millis_{0};
174  uint64_t stop_millis_{0};
175  Sprinkler *controller_{nullptr};
176  SprinklerValve *valve_{nullptr};
178 };
179 
181  public:
183  SprinklerValveRunRequest(size_t valve_number, uint32_t run_duration, SprinklerValveOperator *valve_op);
184  bool has_request();
185  bool has_valve_operator();
186  void set_request_from(SprinklerValveRunRequestOrigin origin);
187  void set_run_duration(uint32_t run_duration);
188  void set_valve(size_t valve_number);
189  void set_valve_operator(SprinklerValveOperator *valve_op);
190  void reset();
191  uint32_t run_duration();
192  size_t valve();
193  optional<size_t> valve_as_opt();
194  SprinklerValveOperator *valve_operator();
195  SprinklerValveRunRequestOrigin request_is_from();
196 
197  protected:
198  bool has_valve_{false};
199  size_t valve_number_{0};
200  uint32_t run_duration_{0};
201  SprinklerValveOperator *valve_op_{nullptr};
203 };
204 
205 class Sprinkler : public Component {
206  public:
207  Sprinkler();
208  Sprinkler(const std::string &name);
209  void setup() override;
210  void loop() override;
211  void dump_config() override;
212 
214  void add_valve(SprinklerControllerSwitch *valve_sw, SprinklerControllerSwitch *enable_sw = nullptr);
215 
217  void add_controller(Sprinkler *other_controller);
218 
220  void set_controller_main_switch(SprinklerControllerSwitch *controller_switch);
221  void set_controller_auto_adv_switch(SprinklerControllerSwitch *auto_adv_switch);
222  void set_controller_queue_enable_switch(SprinklerControllerSwitch *queue_enable_switch);
223  void set_controller_reverse_switch(SprinklerControllerSwitch *reverse_switch);
224  void set_controller_standby_switch(SprinklerControllerSwitch *standby_switch);
225 
227  void set_controller_multiplier_number(SprinklerControllerNumber *multiplier_number);
228  void set_controller_repeat_number(SprinklerControllerNumber *repeat_number);
229 
231  void configure_valve_switch(size_t valve_number, switch_::Switch *valve_switch, uint32_t run_duration);
232  void configure_valve_switch_pulsed(size_t valve_number, switch_::Switch *valve_switch_off,
233  switch_::Switch *valve_switch_on, uint32_t pulse_duration, uint32_t run_duration);
234 
236  void configure_valve_pump_switch(size_t valve_number, switch_::Switch *pump_switch);
237  void configure_valve_pump_switch_pulsed(size_t valve_number, switch_::Switch *pump_switch_off,
238  switch_::Switch *pump_switch_on, uint32_t pulse_duration);
239 
241  void configure_valve_run_duration_number(size_t valve_number, SprinklerControllerNumber *run_duration_number);
242 
244  void set_divider(optional<uint32_t> divider);
245 
247  void set_multiplier(optional<float> multiplier);
248 
250  void set_next_prev_ignore_disabled_valves(bool ignore_disabled);
251 
253  void set_pump_start_delay(uint32_t start_delay);
254 
256  void set_pump_stop_delay(uint32_t stop_delay);
257 
259  void set_valve_start_delay(uint32_t start_delay);
260 
262  void set_valve_stop_delay(uint32_t stop_delay);
263 
266  void set_pump_switch_off_during_valve_open_delay(bool pump_switch_off_during_valve_open_delay);
267 
269  void set_valve_open_delay(uint32_t valve_open_delay);
270 
272  void set_valve_overlap(uint32_t valve_overlap);
273 
275  void set_manual_selection_delay(uint32_t manual_selection_delay);
276 
278  void set_valve_run_duration(optional<size_t> valve_number, optional<uint32_t> run_duration);
279 
281  void set_auto_advance(bool auto_advance);
282 
284  void set_repeat(optional<uint32_t> repeat);
285 
287  void set_queue_enable(bool queue_enable);
288 
290  void set_reverse(bool reverse);
291 
293  void set_standby(bool standby);
294 
296  uint32_t valve_run_duration(size_t valve_number);
297 
299  uint32_t valve_run_duration_adjusted(size_t valve_number);
300 
302  bool auto_advance();
303 
305  float multiplier();
306 
308  optional<uint32_t> repeat();
309 
311  optional<uint32_t> repeat_count();
312 
314  bool queue_enabled();
315 
317  bool reverse();
318 
320  bool standby();
321 
324  void start_from_queue();
325 
328  void start_full_cycle();
329 
331  void start_single_valve(optional<size_t> valve_number, optional<uint32_t> run_duration = nullopt);
332 
335  void queue_valve(optional<size_t> valve_number, optional<uint32_t> run_duration);
336 
338  void clear_queued_valves();
339 
341  void next_valve();
342 
344  void previous_valve();
345 
347  void shutdown(bool clear_queue = false);
348 
350  void pause();
351 
353  void resume();
354 
356  void resume_or_start_full_cycle();
357 
359  void reset_resume();
360 
362  const char *valve_name(size_t valve_number);
363 
365  optional<SprinklerValveRunRequestOrigin> active_valve_request_is_from();
366 
368  optional<size_t> active_valve();
369 
371  optional<size_t> paused_valve();
372 
374  optional<size_t> queued_valve();
375 
378  optional<size_t> manual_valve();
379 
381  size_t number_of_valves();
382 
384  bool is_a_valid_valve(size_t valve_number);
385 
387  bool pump_in_use(SprinklerSwitch *pump_switch);
388 
390  void set_pump_state(SprinklerSwitch *pump_switch, bool state);
391 
393  uint32_t total_cycle_time_all_valves();
394 
396  uint32_t total_cycle_time_enabled_valves();
397 
399  uint32_t total_cycle_time_enabled_incomplete_valves();
400 
402  uint32_t total_queue_time();
403 
405  optional<uint32_t> time_remaining_active_valve();
406 
408  optional<uint32_t> time_remaining_current_operation();
409 
411  bool any_controller_is_active();
412 
415 
417  SprinklerControllerSwitch *control_switch(size_t valve_number);
418 
420  SprinklerControllerSwitch *enable_switch(size_t valve_number);
421 
423  SprinklerSwitch *valve_switch(size_t valve_number);
424 
426  SprinklerSwitch *valve_pump_switch(size_t valve_number);
427 
429  SprinklerSwitch *valve_pump_switch_by_pump_index(size_t pump_index);
430 
431  protected:
433  bool valve_is_enabled_(size_t valve_number);
434 
436  void mark_valve_cycle_complete_(size_t valve_number);
437 
439  bool valve_cycle_complete_(size_t valve_number);
440 
442  optional<size_t> next_valve_number_(optional<size_t> first_valve = nullopt, bool include_disabled = true,
443  bool include_complete = true);
444 
446  optional<size_t> previous_valve_number_(optional<size_t> first_valve = nullopt, bool include_disabled = true,
447  bool include_complete = true);
448 
451  optional<size_t> next_valve_number_in_cycle_(optional<size_t> first_valve = nullopt);
452 
457  void load_next_valve_run_request_(optional<size_t> first_valve = nullopt);
458 
460  bool any_valve_is_enabled_();
461 
464  void start_valve_(SprinklerValveRunRequest *req);
465 
467  void all_valves_off_(bool include_pump = false);
468 
470  void prep_full_cycle_();
471 
473  void reset_cycle_states_();
474 
476  void fsm_request_(size_t requested_valve, uint32_t requested_run_duration = 0);
477 
479  void fsm_kick_();
480 
482  void fsm_transition_();
483 
485  void fsm_transition_from_shutdown_();
486 
488  void fsm_transition_from_valve_run_();
489 
491  void fsm_transition_to_shutdown_();
492 
494  std::string req_as_str_(SprinklerValveRunRequestOrigin origin);
495 
497  std::string state_as_str_(SprinklerState state);
498 
500  void start_timer_(SprinklerTimerIndex timer_index);
501  bool cancel_timer_(SprinklerTimerIndex timer_index);
503  bool timer_active_(SprinklerTimerIndex timer_index);
505  void set_timer_duration_(SprinklerTimerIndex timer_index, uint32_t time);
507  uint32_t timer_duration_(SprinklerTimerIndex timer_index);
508  std::function<void()> timer_cbf_(SprinklerTimerIndex timer_index);
509 
511  void valve_selection_callback_();
512  void sm_timer_callback_();
513 
515  const uint8_t max_queue_size_{100};
516 
518  bool next_prev_ignore_disabled_{false};
519 
521  bool pump_switch_off_during_valve_open_delay_{false};
522 
524  bool valve_overlap_{false};
525 
527  bool start_delay_is_valve_delay_{false};
528  bool stop_delay_is_valve_delay_{false};
529 
531  uint32_t start_delay_{0};
532  uint32_t stop_delay_{0};
533 
534  std::string name_;
535 
538 
541 
544 
547 
550 
553 
556 
559 
562 
565 
567  uint32_t repeat_count_{0};
568 
570  float multiplier_{1.0};
571 
573  std::vector<SprinklerQueueItem> queued_valves_;
574 
576  std::vector<SprinklerSwitch> pump_;
577 
579  std::vector<SprinklerValve> valve_;
580 
582  std::vector<SprinklerValveOperator> valve_op_{2};
583 
585  std::vector<SprinklerTimer> timer_{};
586 
588  std::vector<Sprinkler *> other_controllers_;
589 
591  SprinklerControllerSwitch *auto_adv_sw_{nullptr};
592  SprinklerControllerSwitch *controller_sw_{nullptr};
593  SprinklerControllerSwitch *queue_enable_sw_{nullptr};
594  SprinklerControllerSwitch *reverse_sw_{nullptr};
595  SprinklerControllerSwitch *standby_sw_{nullptr};
596 
598  SprinklerControllerNumber *multiplier_number_{nullptr};
599  SprinklerControllerNumber *repeat_number_{nullptr};
600 
601  std::unique_ptr<ShutdownAction<>> sprinkler_shutdown_action_;
602  std::unique_ptr<ShutdownAction<>> sprinkler_standby_shutdown_action_;
603  std::unique_ptr<ResumeOrStartAction<>> sprinkler_resumeorstart_action_;
604 
605  std::unique_ptr<Automation<>> sprinkler_turn_off_automation_;
606  std::unique_ptr<Automation<>> sprinkler_turn_on_automation_;
607  std::unique_ptr<Automation<>> sprinkler_standby_turn_on_automation_;
608 };
609 
610 } // namespace sprinkler
611 } // namespace esphome
void setup()
Base class for all switches.
Definition: switch.h:39
const char * name
Definition: stm32flash.h:78
void set_off_switch(switch_::Switch *off_switch)
Definition: sprinkler.h:57
SprinklerControllerSwitch * controller_switch
Definition: sprinkler.h:90
SprinklerValveRunRequest next_req_
The next run request for the controller to consume after active_req_ is complete. ...
Definition: sprinkler.h:543
std::unique_ptr< Automation<> > sprinkler_standby_turn_on_automation_
Definition: sprinkler.h:607
optional< uint32_t > resume_duration_
Set from time_remaining() when paused.
Definition: sprinkler.h:558
std::vector< SprinklerValve > valve_
Sprinkler valve objects.
Definition: sprinkler.h:579
optional< uint32_t > switching_delay_
Valve switching delay.
Definition: sprinkler.h:564
void set_pulse_duration(uint32_t pulse_duration)
Definition: sprinkler.h:59
Trigger< float > * get_set_trigger() const
Definition: sprinkler.h:108
std::unique_ptr< ResumeOrStartAction<> > sprinkler_resumeorstart_action_
Definition: sprinkler.h:603
optional< size_t > pump_switch_index
Definition: sprinkler.h:94
std::unique_ptr< Automation<> > valve_turn_off_automation
Definition: sprinkler.h:98
std::vector< Sprinkler * > other_controllers_
Other Sprinkler instances we should be aware of (used to check if pumps are in use) ...
Definition: sprinkler.h:588
void set_on_switch(switch_::Switch *on_switch)
Definition: sprinkler.h:58
switch_::Switch * on_switch()
Definition: sprinkler.h:65
std::unique_ptr< Automation<> > sprinkler_turn_on_automation_
Definition: sprinkler.h:606
const nullopt_t nullopt((nullopt_t::init()))
std::function< void()> func
Definition: sprinkler.h:85
SprinklerControllerNumber * run_duration_number
Definition: sprinkler.h:89
void set_initial_value(float initial_value)
Definition: sprinkler.h:109
Base-class for all numbers.
Definition: number.h:39
SprinklerState controller_state()
returns the current state of the sprinkler controller
Definition: sprinkler.h:414
const float PROCESSOR
For components that use data from sensors like displays.
Definition: component.cpp:20
uint16_t reset
Definition: ina226.h:39
optional< size_t > manual_valve_
The number of the manually selected valve currently selected.
Definition: sprinkler.h:549
optional< uint32_t > target_repeats_
Set the number of times to repeat a full cycle.
Definition: sprinkler.h:555
const std::string MIN_STR
Definition: sprinkler.h:14
void set_restore_value(bool restore_value)
Definition: sprinkler.h:110
std::vector< SprinklerSwitch > pump_
Sprinkler valve pump objects.
Definition: sprinkler.h:576
SprinklerValveRunRequest prev_req_
The previous run request the controller processed.
Definition: sprinkler.h:546
optional< size_t > paused_valve_
The number of the valve to resume from (if paused)
Definition: sprinkler.h:552
std::unique_ptr< StartSingleValveAction<> > valve_resumeorstart_action
Definition: sprinkler.h:97
void sync_valve_state(bool latch_state)
Definition: sprinkler.cpp:71
std::unique_ptr< ShutdownAction<> > sprinkler_shutdown_action_
Definition: sprinkler.h:601
std::unique_ptr< Automation<> > sprinkler_turn_off_automation_
Definition: sprinkler.h:605
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
optional< uint32_t > manual_selection_delay_
Manual switching delay.
Definition: sprinkler.h:561
std::unique_ptr< Automation<> > valve_turn_on_automation
Definition: sprinkler.h:99
std::vector< SprinklerQueueItem > queued_valves_
Queue of valves to activate next, regardless of auto-advance.
Definition: sprinkler.h:573
SprinklerControllerSwitch * enable_switch
Definition: sprinkler.h:91
std::unique_ptr< ShutdownAction<> > sprinkler_standby_shutdown_action_
Definition: sprinkler.h:602
switch_::Switch * off_switch()
Definition: sprinkler.h:64
SprinklerValveRunRequest active_req_
The valve run request that is currently active.
Definition: sprinkler.h:540
std::unique_ptr< ShutdownAction<> > valve_shutdown_action
Definition: sprinkler.h:96