mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Sprinkler fixes (#4816)
This commit is contained in:
		| @@ -599,15 +599,6 @@ async def to_code(config): | |||||||
|             ) |             ) | ||||||
|             cg.add(var.set_controller_auto_adv_switch(sw_aa_var)) |             cg.add(var.set_controller_auto_adv_switch(sw_aa_var)) | ||||||
|  |  | ||||||
|             if CONF_QUEUE_ENABLE_SWITCH in sprinkler_controller: |  | ||||||
|                 sw_qen_var = await switch.new_switch( |  | ||||||
|                     sprinkler_controller[CONF_QUEUE_ENABLE_SWITCH] |  | ||||||
|                 ) |  | ||||||
|                 await cg.register_component( |  | ||||||
|                     sw_qen_var, sprinkler_controller[CONF_QUEUE_ENABLE_SWITCH] |  | ||||||
|                 ) |  | ||||||
|                 cg.add(var.set_controller_queue_enable_switch(sw_qen_var)) |  | ||||||
|  |  | ||||||
|             if CONF_REVERSE_SWITCH in sprinkler_controller: |             if CONF_REVERSE_SWITCH in sprinkler_controller: | ||||||
|                 sw_rev_var = await switch.new_switch( |                 sw_rev_var = await switch.new_switch( | ||||||
|                     sprinkler_controller[CONF_REVERSE_SWITCH] |                     sprinkler_controller[CONF_REVERSE_SWITCH] | ||||||
| @@ -617,78 +608,83 @@ async def to_code(config): | |||||||
|                 ) |                 ) | ||||||
|                 cg.add(var.set_controller_reverse_switch(sw_rev_var)) |                 cg.add(var.set_controller_reverse_switch(sw_rev_var)) | ||||||
|  |  | ||||||
|             if CONF_STANDBY_SWITCH in sprinkler_controller: |         if CONF_STANDBY_SWITCH in sprinkler_controller: | ||||||
|                 sw_stb_var = await switch.new_switch( |             sw_stb_var = await switch.new_switch( | ||||||
|                     sprinkler_controller[CONF_STANDBY_SWITCH] |                 sprinkler_controller[CONF_STANDBY_SWITCH] | ||||||
|                 ) |             ) | ||||||
|                 await cg.register_component( |             await cg.register_component( | ||||||
|                     sw_stb_var, sprinkler_controller[CONF_STANDBY_SWITCH] |                 sw_stb_var, sprinkler_controller[CONF_STANDBY_SWITCH] | ||||||
|                 ) |             ) | ||||||
|                 cg.add(var.set_controller_standby_switch(sw_stb_var)) |             cg.add(var.set_controller_standby_switch(sw_stb_var)) | ||||||
|  |  | ||||||
|             if CONF_MULTIPLIER_NUMBER in sprinkler_controller: |         if CONF_QUEUE_ENABLE_SWITCH in sprinkler_controller: | ||||||
|                 num_mult_var = await number.new_number( |             sw_qen_var = await switch.new_switch( | ||||||
|                     sprinkler_controller[CONF_MULTIPLIER_NUMBER], |                 sprinkler_controller[CONF_QUEUE_ENABLE_SWITCH] | ||||||
|                     min_value=sprinkler_controller[CONF_MULTIPLIER_NUMBER][ |             ) | ||||||
|                         CONF_MIN_VALUE |             await cg.register_component( | ||||||
|                     ], |                 sw_qen_var, sprinkler_controller[CONF_QUEUE_ENABLE_SWITCH] | ||||||
|                     max_value=sprinkler_controller[CONF_MULTIPLIER_NUMBER][ |             ) | ||||||
|                         CONF_MAX_VALUE |             cg.add(var.set_controller_queue_enable_switch(sw_qen_var)) | ||||||
|                     ], |  | ||||||
|                     step=sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_STEP], |         if CONF_MULTIPLIER_NUMBER in sprinkler_controller: | ||||||
|  |             num_mult_var = await number.new_number( | ||||||
|  |                 sprinkler_controller[CONF_MULTIPLIER_NUMBER], | ||||||
|  |                 min_value=sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_MIN_VALUE], | ||||||
|  |                 max_value=sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_MAX_VALUE], | ||||||
|  |                 step=sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_STEP], | ||||||
|  |             ) | ||||||
|  |             await cg.register_component( | ||||||
|  |                 num_mult_var, sprinkler_controller[CONF_MULTIPLIER_NUMBER] | ||||||
|  |             ) | ||||||
|  |             cg.add( | ||||||
|  |                 num_mult_var.set_initial_value( | ||||||
|  |                     sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_INITIAL_VALUE] | ||||||
|                 ) |                 ) | ||||||
|                 await cg.register_component( |             ) | ||||||
|                     num_mult_var, sprinkler_controller[CONF_MULTIPLIER_NUMBER] |             cg.add( | ||||||
|  |                 num_mult_var.set_restore_value( | ||||||
|  |                     sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_RESTORE_VALUE] | ||||||
|                 ) |                 ) | ||||||
|                 cg.add( |             ) | ||||||
|                     num_mult_var.set_initial_value( |  | ||||||
|                         sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_INITIAL_VALUE] |             if CONF_SET_ACTION in sprinkler_controller[CONF_MULTIPLIER_NUMBER]: | ||||||
|                     ) |                 await automation.build_automation( | ||||||
|                 ) |                     num_mult_var.get_set_trigger(), | ||||||
|                 cg.add( |                     [(float, "x")], | ||||||
|                     num_mult_var.set_restore_value( |                     sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_SET_ACTION], | ||||||
|                         sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_RESTORE_VALUE] |  | ||||||
|                     ) |  | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|                 if CONF_SET_ACTION in sprinkler_controller[CONF_MULTIPLIER_NUMBER]: |             cg.add(var.set_controller_multiplier_number(num_mult_var)) | ||||||
|                     await automation.build_automation( |  | ||||||
|                         num_mult_var.get_set_trigger(), |  | ||||||
|                         [(float, "x")], |  | ||||||
|                         sprinkler_controller[CONF_MULTIPLIER_NUMBER][CONF_SET_ACTION], |  | ||||||
|                     ) |  | ||||||
|  |  | ||||||
|                 cg.add(var.set_controller_multiplier_number(num_mult_var)) |         if CONF_REPEAT_NUMBER in sprinkler_controller: | ||||||
|  |             num_repeat_var = await number.new_number( | ||||||
|  |                 sprinkler_controller[CONF_REPEAT_NUMBER], | ||||||
|  |                 min_value=sprinkler_controller[CONF_REPEAT_NUMBER][CONF_MIN_VALUE], | ||||||
|  |                 max_value=sprinkler_controller[CONF_REPEAT_NUMBER][CONF_MAX_VALUE], | ||||||
|  |                 step=sprinkler_controller[CONF_REPEAT_NUMBER][CONF_STEP], | ||||||
|  |             ) | ||||||
|  |             await cg.register_component( | ||||||
|  |                 num_repeat_var, sprinkler_controller[CONF_REPEAT_NUMBER] | ||||||
|  |             ) | ||||||
|  |             cg.add( | ||||||
|  |                 num_repeat_var.set_initial_value( | ||||||
|  |                     sprinkler_controller[CONF_REPEAT_NUMBER][CONF_INITIAL_VALUE] | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |             cg.add( | ||||||
|  |                 num_repeat_var.set_restore_value( | ||||||
|  |                     sprinkler_controller[CONF_REPEAT_NUMBER][CONF_RESTORE_VALUE] | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |  | ||||||
|             if CONF_REPEAT_NUMBER in sprinkler_controller: |             if CONF_SET_ACTION in sprinkler_controller[CONF_REPEAT_NUMBER]: | ||||||
|                 num_repeat_var = await number.new_number( |                 await automation.build_automation( | ||||||
|                     sprinkler_controller[CONF_REPEAT_NUMBER], |                     num_repeat_var.get_set_trigger(), | ||||||
|                     min_value=sprinkler_controller[CONF_REPEAT_NUMBER][CONF_MIN_VALUE], |                     [(float, "x")], | ||||||
|                     max_value=sprinkler_controller[CONF_REPEAT_NUMBER][CONF_MAX_VALUE], |                     sprinkler_controller[CONF_REPEAT_NUMBER][CONF_SET_ACTION], | ||||||
|                     step=sprinkler_controller[CONF_REPEAT_NUMBER][CONF_STEP], |  | ||||||
|                 ) |  | ||||||
|                 await cg.register_component( |  | ||||||
|                     num_repeat_var, sprinkler_controller[CONF_REPEAT_NUMBER] |  | ||||||
|                 ) |  | ||||||
|                 cg.add( |  | ||||||
|                     num_repeat_var.set_initial_value( |  | ||||||
|                         sprinkler_controller[CONF_REPEAT_NUMBER][CONF_INITIAL_VALUE] |  | ||||||
|                     ) |  | ||||||
|                 ) |  | ||||||
|                 cg.add( |  | ||||||
|                     num_repeat_var.set_restore_value( |  | ||||||
|                         sprinkler_controller[CONF_REPEAT_NUMBER][CONF_RESTORE_VALUE] |  | ||||||
|                     ) |  | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|                 if CONF_SET_ACTION in sprinkler_controller[CONF_REPEAT_NUMBER]: |             cg.add(var.set_controller_repeat_number(num_repeat_var)) | ||||||
|                     await automation.build_automation( |  | ||||||
|                         num_repeat_var.get_set_trigger(), |  | ||||||
|                         [(float, "x")], |  | ||||||
|                         sprinkler_controller[CONF_REPEAT_NUMBER][CONF_SET_ACTION], |  | ||||||
|                     ) |  | ||||||
|  |  | ||||||
|                 cg.add(var.set_controller_repeat_number(num_repeat_var)) |  | ||||||
|  |  | ||||||
|         for valve in sprinkler_controller[CONF_VALVES]: |         for valve in sprinkler_controller[CONF_VALVES]: | ||||||
|             sw_valve_var = await switch.new_switch(valve[CONF_VALVE_SWITCH]) |             sw_valve_var = await switch.new_switch(valve[CONF_VALVE_SWITCH]) | ||||||
|   | |||||||
| @@ -147,22 +147,22 @@ SprinklerValveOperator::SprinklerValveOperator(SprinklerValve *valve, Sprinkler | |||||||
|     : controller_(controller), valve_(valve) {} |     : controller_(controller), valve_(valve) {} | ||||||
|  |  | ||||||
| void SprinklerValveOperator::loop() { | void SprinklerValveOperator::loop() { | ||||||
|   if (millis() >= this->pinned_millis_) {  // dummy check |   if (millis() >= this->start_millis_) {  // dummy check | ||||||
|     switch (this->state_) { |     switch (this->state_) { | ||||||
|       case STARTING: |       case STARTING: | ||||||
|         if (millis() > (this->pinned_millis_ + this->start_delay_)) { |         if (millis() > (this->start_millis_ + this->start_delay_)) { | ||||||
|           this->run_();  // start_delay_ has been exceeded, so ensure both valves are on and update the state |           this->run_();  // start_delay_ has been exceeded, so ensure both valves are on and update the state | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|       case ACTIVE: |       case ACTIVE: | ||||||
|         if (millis() > (this->pinned_millis_ + this->start_delay_ + this->run_duration_)) { |         if (millis() > (this->start_millis_ + this->start_delay_ + this->run_duration_)) { | ||||||
|           this->stop();  // start_delay_ + run_duration_ has been exceeded, start shutting down |           this->stop();  // start_delay_ + run_duration_ has been exceeded, start shutting down | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|       case STOPPING: |       case STOPPING: | ||||||
|         if (millis() > (this->pinned_millis_ + this->stop_delay_)) { |         if (millis() > (this->stop_millis_ + this->stop_delay_)) { | ||||||
|           this->kill_();  // stop_delay_has been exceeded, ensure all valves are off |           this->kill_();  // stop_delay_has been exceeded, ensure all valves are off | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
| @@ -183,11 +183,12 @@ void SprinklerValveOperator::set_controller(Sprinkler *controller) { | |||||||
|  |  | ||||||
| void SprinklerValveOperator::set_valve(SprinklerValve *valve) { | void SprinklerValveOperator::set_valve(SprinklerValve *valve) { | ||||||
|   if (valve != nullptr) { |   if (valve != nullptr) { | ||||||
|     this->state_ = IDLE;       // reset state |     this->state_ = IDLE;      // reset state | ||||||
|     this->run_duration_ = 0;   // reset to ensure the valve isn't started without updating it |     this->run_duration_ = 0;  // reset to ensure the valve isn't started without updating it | ||||||
|     this->pinned_millis_ = 0;  // reset because (new) valve has not been started yet |     this->start_millis_ = 0;  // reset because (new) valve has not been started yet | ||||||
|     this->kill_();             // ensure everything is off before we let go! |     this->stop_millis_ = 0;   // reset because (new) valve has not been started yet | ||||||
|     this->valve_ = valve;      // finally, set the pointer to the new valve |     this->kill_();            // ensure everything is off before we let go! | ||||||
|  |     this->valve_ = valve;     // finally, set the pointer to the new valve | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -221,7 +222,8 @@ void SprinklerValveOperator::start() { | |||||||
|   } else { |   } else { | ||||||
|     this->run_();  // there is no start_delay_, so just start the pump and valve |     this->run_();  // there is no start_delay_, so just start the pump and valve | ||||||
|   } |   } | ||||||
|   this->pinned_millis_ = millis();  // save the time the start request was made |   this->stop_millis_ = 0; | ||||||
|  |   this->start_millis_ = millis();  // save the time the start request was made | ||||||
| } | } | ||||||
|  |  | ||||||
| void SprinklerValveOperator::stop() { | void SprinklerValveOperator::stop() { | ||||||
| @@ -238,19 +240,33 @@ void SprinklerValveOperator::stop() { | |||||||
|     if (this->pump_switch()->state()) {  // if the pump is still on at this point, it may be in use... |     if (this->pump_switch()->state()) {  // if the pump is still on at this point, it may be in use... | ||||||
|       this->valve_off_();                // ...so just switch the valve off now to ensure consistent run time |       this->valve_off_();                // ...so just switch the valve off now to ensure consistent run time | ||||||
|     } |     } | ||||||
|     this->pinned_millis_ = millis();  // save the time the stop request was made |  | ||||||
|   } else { |   } else { | ||||||
|     this->kill_();  // there is no stop_delay_, so just stop the pump and valve |     this->kill_();  // there is no stop_delay_, so just stop the pump and valve | ||||||
|   } |   } | ||||||
|  |   this->stop_millis_ = millis();  // save the time the stop request was made | ||||||
| } | } | ||||||
|  |  | ||||||
| uint32_t SprinklerValveOperator::run_duration() { return this->run_duration_; } | uint32_t SprinklerValveOperator::run_duration() { return this->run_duration_ / 1000; } | ||||||
|  |  | ||||||
| uint32_t SprinklerValveOperator::time_remaining() { | uint32_t SprinklerValveOperator::time_remaining() { | ||||||
|   if ((this->state_ == STARTING) || (this->state_ == ACTIVE)) { |   if (this->start_millis_ == 0) { | ||||||
|     return (this->pinned_millis_ + this->start_delay_ + this->run_duration_ - millis()) / 1000; |     return this->run_duration();  // hasn't been started yet | ||||||
|   } |   } | ||||||
|   return 0; |  | ||||||
|  |   if (this->stop_millis_) { | ||||||
|  |     if (this->stop_millis_ - this->start_millis_ >= this->start_delay_ + this->run_duration_) { | ||||||
|  |       return 0;  // valve was active for more than its configured duration, so we are done | ||||||
|  |     } else { | ||||||
|  |       // we're stopped; return time remaining | ||||||
|  |       return (this->run_duration_ - (this->stop_millis_ - this->start_millis_)) / 1000; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   auto completed_millis = this->start_millis_ + this->start_delay_ + this->run_duration_; | ||||||
|  |   if (completed_millis > millis()) { | ||||||
|  |     return (completed_millis - millis()) / 1000;  // running now | ||||||
|  |   } | ||||||
|  |   return 0;  // run completed | ||||||
| } | } | ||||||
|  |  | ||||||
| SprinklerState SprinklerValveOperator::state() { return this->state_; } | SprinklerState SprinklerValveOperator::state() { return this->state_; } | ||||||
| @@ -386,6 +402,9 @@ void Sprinkler::loop() { | |||||||
|   for (auto &vo : this->valve_op_) { |   for (auto &vo : this->valve_op_) { | ||||||
|     vo.loop(); |     vo.loop(); | ||||||
|   } |   } | ||||||
|  |   if (this->prev_req_.has_request() && this->prev_req_.valve_operator()->state() == IDLE) { | ||||||
|  |     this->prev_req_.reset(); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void Sprinkler::add_valve(SprinklerControllerSwitch *valve_sw, SprinklerControllerSwitch *enable_sw) { | void Sprinkler::add_valve(SprinklerControllerSwitch *valve_sw, SprinklerControllerSwitch *enable_sw) { | ||||||
| @@ -732,7 +751,7 @@ bool Sprinkler::auto_advance() { | |||||||
|   if (this->auto_adv_sw_ != nullptr) { |   if (this->auto_adv_sw_ != nullptr) { | ||||||
|     return this->auto_adv_sw_->state; |     return this->auto_adv_sw_->state; | ||||||
|   } |   } | ||||||
|   return false; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| float Sprinkler::multiplier() { | float Sprinkler::multiplier() { | ||||||
| @@ -972,7 +991,14 @@ optional<SprinklerValveRunRequestOrigin> Sprinkler::active_valve_request_is_from | |||||||
|   return nullopt; |   return nullopt; | ||||||
| } | } | ||||||
|  |  | ||||||
| optional<size_t> Sprinkler::active_valve() { return this->active_req_.valve_as_opt(); } | optional<size_t> Sprinkler::active_valve() { | ||||||
|  |   if (!this->valve_overlap_ && this->prev_req_.has_request() && | ||||||
|  |       (this->prev_req_.valve_operator()->state() == STARTING || this->prev_req_.valve_operator()->state() == ACTIVE)) { | ||||||
|  |     return this->prev_req_.valve_as_opt(); | ||||||
|  |   } | ||||||
|  |   return this->active_req_.valve_as_opt(); | ||||||
|  | } | ||||||
|  |  | ||||||
| optional<size_t> Sprinkler::paused_valve() { return this->paused_valve_; } | optional<size_t> Sprinkler::paused_valve() { return this->paused_valve_; } | ||||||
|  |  | ||||||
| optional<size_t> Sprinkler::queued_valve() { | optional<size_t> Sprinkler::queued_valve() { | ||||||
| @@ -1097,22 +1123,35 @@ uint32_t Sprinkler::total_cycle_time_enabled_valves() { | |||||||
|  |  | ||||||
| uint32_t Sprinkler::total_cycle_time_enabled_incomplete_valves() { | uint32_t Sprinkler::total_cycle_time_enabled_incomplete_valves() { | ||||||
|   uint32_t total_time_remaining = 0; |   uint32_t total_time_remaining = 0; | ||||||
|   uint32_t valve_count = 0; |   uint32_t enabled_valve_count = 0; | ||||||
|  |   uint32_t incomplete_valve_count = 0; | ||||||
|  |  | ||||||
|   for (size_t valve = 0; valve < this->number_of_valves(); valve++) { |   for (size_t valve = 0; valve < this->number_of_valves(); valve++) { | ||||||
|     if (this->valve_is_enabled_(valve) && !this->valve_cycle_complete_(valve)) { |     if (this->valve_is_enabled_(valve)) { | ||||||
|       if (!this->active_valve().has_value() || (valve != this->active_valve().value())) { |       enabled_valve_count++; | ||||||
|         total_time_remaining += this->valve_run_duration_adjusted(valve); |       if (!this->valve_cycle_complete_(valve)) { | ||||||
|         valve_count++; |         if (!this->active_valve().has_value() || (valve != this->active_valve().value())) { | ||||||
|  |           total_time_remaining += this->valve_run_duration_adjusted(valve); | ||||||
|  |           incomplete_valve_count++; | ||||||
|  |         } else { | ||||||
|  |           // to get here, there must be an active valve and this valve must be equal to 'valve' | ||||||
|  |           if (this->active_req_.valve_operator() == nullptr) {  // no SVO has been assigned yet so it hasn't started | ||||||
|  |             total_time_remaining += this->valve_run_duration_adjusted(valve); | ||||||
|  |             incomplete_valve_count++; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (valve_count) { |   if (incomplete_valve_count >= enabled_valve_count) { | ||||||
|  |     incomplete_valve_count--; | ||||||
|  |   } | ||||||
|  |   if (incomplete_valve_count) { | ||||||
|     if (this->valve_overlap_) { |     if (this->valve_overlap_) { | ||||||
|       total_time_remaining -= this->switching_delay_.value_or(0) * (valve_count - 1); |       total_time_remaining -= this->switching_delay_.value_or(0) * incomplete_valve_count; | ||||||
|     } else { |     } else { | ||||||
|       total_time_remaining += this->switching_delay_.value_or(0) * (valve_count - 1); |       total_time_remaining += this->switching_delay_.value_or(0) * incomplete_valve_count; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1149,31 +1188,32 @@ optional<uint32_t> Sprinkler::time_remaining_active_valve() { | |||||||
|       return this->active_req_.valve_operator()->time_remaining(); |       return this->active_req_.valve_operator()->time_remaining(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   for (auto &vo : this->valve_op_) {  // ...else return the value from the first non-IDLE SprinklerValveOperator |   if (this->prev_req_.has_request()) {  // try to return the value based on prev_req_... | ||||||
|     if (vo.state() != IDLE) { |     if (this->prev_req_.valve_operator() != nullptr) { | ||||||
|       return vo.time_remaining(); |       return this->prev_req_.valve_operator()->time_remaining(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   return nullopt; |   return nullopt; | ||||||
| } | } | ||||||
|  |  | ||||||
| optional<uint32_t> Sprinkler::time_remaining_current_operation() { | optional<uint32_t> Sprinkler::time_remaining_current_operation() { | ||||||
|   auto total_time_remaining = this->time_remaining_active_valve(); |   if (!this->time_remaining_active_valve().has_value() && this->state_ == IDLE) { | ||||||
|  |     return nullopt; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   if (total_time_remaining.has_value()) { |   auto total_time_remaining = this->time_remaining_active_valve().value_or(0); | ||||||
|     if (this->auto_advance()) { |   if (this->auto_advance()) { | ||||||
|       total_time_remaining = total_time_remaining.value() + this->total_cycle_time_enabled_incomplete_valves(); |     total_time_remaining += this->total_cycle_time_enabled_incomplete_valves(); | ||||||
|       total_time_remaining = |     if (this->repeat().value_or(0) > 0) { | ||||||
|           total_time_remaining.value() + |       total_time_remaining += | ||||||
|           (this->total_cycle_time_enabled_valves() * (this->repeat().value_or(0) - this->repeat_count().value_or(0))); |           (this->total_cycle_time_enabled_valves() * (this->repeat().value_or(0) - this->repeat_count().value_or(0))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (this->queue_enabled()) { |  | ||||||
|       total_time_remaining = total_time_remaining.value() + this->total_queue_time(); |  | ||||||
|     } |  | ||||||
|     return total_time_remaining; |  | ||||||
|   } |   } | ||||||
|   return nullopt; |  | ||||||
|  |   if (this->queue_enabled()) { | ||||||
|  |     total_time_remaining += this->total_queue_time(); | ||||||
|  |   } | ||||||
|  |   return total_time_remaining; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool Sprinkler::any_controller_is_active() { | bool Sprinkler::any_controller_is_active() { | ||||||
| @@ -1305,6 +1345,12 @@ optional<size_t> Sprinkler::next_valve_number_in_cycle_(const optional<size_t> f | |||||||
| } | } | ||||||
|  |  | ||||||
| void Sprinkler::load_next_valve_run_request_(const optional<size_t> first_valve) { | void Sprinkler::load_next_valve_run_request_(const optional<size_t> first_valve) { | ||||||
|  |   if (this->active_req_.has_request()) { | ||||||
|  |     this->prev_req_ = this->active_req_; | ||||||
|  |   } else { | ||||||
|  |     this->prev_req_.reset(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   if (this->next_req_.has_request()) { |   if (this->next_req_.has_request()) { | ||||||
|     if (!this->next_req_.run_duration()) {  // ensure the run duration is set correctly for consumption later on |     if (!this->next_req_.run_duration()) {  // ensure the run duration is set correctly for consumption later on | ||||||
|       this->next_req_.set_run_duration(this->valve_run_duration_adjusted(this->next_req_.valve())); |       this->next_req_.set_run_duration(this->valve_run_duration_adjusted(this->next_req_.valve())); | ||||||
|   | |||||||
| @@ -170,7 +170,8 @@ class SprinklerValveOperator { | |||||||
|   uint32_t start_delay_{0}; |   uint32_t start_delay_{0}; | ||||||
|   uint32_t stop_delay_{0}; |   uint32_t stop_delay_{0}; | ||||||
|   uint32_t run_duration_{0}; |   uint32_t run_duration_{0}; | ||||||
|   uint64_t pinned_millis_{0}; |   uint64_t start_millis_{0}; | ||||||
|  |   uint64_t stop_millis_{0}; | ||||||
|   Sprinkler *controller_{nullptr}; |   Sprinkler *controller_{nullptr}; | ||||||
|   SprinklerValve *valve_{nullptr}; |   SprinklerValve *valve_{nullptr}; | ||||||
|   SprinklerState state_{IDLE}; |   SprinklerState state_{IDLE}; | ||||||
| @@ -538,15 +539,18 @@ class Sprinkler : public Component { | |||||||
|   /// The valve run request that is currently active |   /// The valve run request that is currently active | ||||||
|   SprinklerValveRunRequest active_req_; |   SprinklerValveRunRequest active_req_; | ||||||
|  |  | ||||||
|  |   /// The next run request for the controller to consume after active_req_ is complete | ||||||
|  |   SprinklerValveRunRequest next_req_; | ||||||
|  |  | ||||||
|  |   /// The previous run request the controller processed | ||||||
|  |   SprinklerValveRunRequest prev_req_; | ||||||
|  |  | ||||||
|   /// The number of the manually selected valve currently selected |   /// The number of the manually selected valve currently selected | ||||||
|   optional<size_t> manual_valve_; |   optional<size_t> manual_valve_; | ||||||
|  |  | ||||||
|   /// The number of the valve to resume from (if paused) |   /// The number of the valve to resume from (if paused) | ||||||
|   optional<size_t> paused_valve_; |   optional<size_t> paused_valve_; | ||||||
|  |  | ||||||
|   /// The next run request for the controller to consume after active_req_ is complete |  | ||||||
|   SprinklerValveRunRequest next_req_; |  | ||||||
|  |  | ||||||
|   /// Set the number of times to repeat a full cycle |   /// Set the number of times to repeat a full cycle | ||||||
|   optional<uint32_t> target_repeats_; |   optional<uint32_t> target_repeats_; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user