mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	slow_pwm: allow to restart a cycle on state change (#3004)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							c6cbe2748e
						
					
				
				
					commit
					a6a9ebfde2
				
			| @@ -15,6 +15,7 @@ slow_pwm_ns = cg.esphome_ns.namespace("slow_pwm") | |||||||
| SlowPWMOutput = slow_pwm_ns.class_("SlowPWMOutput", output.FloatOutput, cg.Component) | SlowPWMOutput = slow_pwm_ns.class_("SlowPWMOutput", output.FloatOutput, cg.Component) | ||||||
|  |  | ||||||
| CONF_STATE_CHANGE_ACTION = "state_change_action" | CONF_STATE_CHANGE_ACTION = "state_change_action" | ||||||
|  | CONF_RESTART_CYCLE_ON_STATE_CHANGE = "restart_cycle_on_state_change" | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend( | CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend( | ||||||
|     { |     { | ||||||
| @@ -37,6 +38,7 @@ CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend( | |||||||
|             cv.positive_time_period_milliseconds, |             cv.positive_time_period_milliseconds, | ||||||
|             cv.Range(min=core.TimePeriod(milliseconds=100)), |             cv.Range(min=core.TimePeriod(milliseconds=100)), | ||||||
|         ), |         ), | ||||||
|  |         cv.Optional(CONF_RESTART_CYCLE_ON_STATE_CHANGE, default=False): cv.boolean, | ||||||
|     } |     } | ||||||
| ).extend(cv.COMPONENT_SCHEMA) | ).extend(cv.COMPONENT_SCHEMA) | ||||||
|  |  | ||||||
| @@ -63,3 +65,8 @@ async def to_code(config): | |||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     cg.add(var.set_period(config[CONF_PERIOD])) |     cg.add(var.set_period(config[CONF_PERIOD])) | ||||||
|  |     cg.add( | ||||||
|  |         var.set_restart_cycle_on_state_change( | ||||||
|  |             config[CONF_RESTART_CYCLE_ON_STATE_CHANGE] | ||||||
|  |         ) | ||||||
|  |     ) | ||||||
|   | |||||||
| @@ -18,6 +18,12 @@ void SlowPWMOutput::set_output_state_(bool new_state) { | |||||||
|     this->pin_->digital_write(new_state); |     this->pin_->digital_write(new_state); | ||||||
|   } |   } | ||||||
|   if (new_state != current_state_) { |   if (new_state != current_state_) { | ||||||
|  |     if (this->pin_) { | ||||||
|  |       ESP_LOGV(TAG, "Switching output pin %s to %s", this->pin_->dump_summary().c_str(), ONOFF(new_state)); | ||||||
|  |     } else { | ||||||
|  |       ESP_LOGV(TAG, "Switching to %s", ONOFF(new_state)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (this->state_change_trigger_) { |     if (this->state_change_trigger_) { | ||||||
|       this->state_change_trigger_->trigger(new_state); |       this->state_change_trigger_->trigger(new_state); | ||||||
|     } |     } | ||||||
| @@ -36,16 +42,12 @@ void SlowPWMOutput::loop() { | |||||||
|   uint32_t now = millis(); |   uint32_t now = millis(); | ||||||
|   float scaled_state = this->state_ * this->period_; |   float scaled_state = this->state_ * this->period_; | ||||||
|  |  | ||||||
|   if (now - this->period_start_time_ >= this->period_) { |   if (now >= this->period_start_time_ + this->period_) { | ||||||
|     ESP_LOGVV(TAG, "End of period. State: %f, Scaled state: %f", this->state_, scaled_state); |     ESP_LOGVV(TAG, "End of period. State: %f, Scaled state: %f", this->state_, scaled_state); | ||||||
|     this->period_start_time_ += this->period_; |     this->period_start_time_ += this->period_; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (scaled_state > now - this->period_start_time_) { |   this->set_output_state_(now < this->period_start_time_ + scaled_state); | ||||||
|     this->set_output_state_(true); |  | ||||||
|   } else { |  | ||||||
|     this->set_output_state_(false); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void SlowPWMOutput::dump_config() { | void SlowPWMOutput::dump_config() { | ||||||
| @@ -58,8 +60,15 @@ void SlowPWMOutput::dump_config() { | |||||||
|   if (this->turn_off_trigger_) |   if (this->turn_off_trigger_) | ||||||
|     ESP_LOGCONFIG(TAG, "  Turn off automation configured"); |     ESP_LOGCONFIG(TAG, "  Turn off automation configured"); | ||||||
|   ESP_LOGCONFIG(TAG, "  Period: %d ms", this->period_); |   ESP_LOGCONFIG(TAG, "  Period: %d ms", this->period_); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Restart cycle on state change: %s", YESNO(this->restart_cycle_on_state_change_)); | ||||||
|   LOG_FLOAT_OUTPUT(this); |   LOG_FLOAT_OUTPUT(this); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void SlowPWMOutput::write_state(float state) { | ||||||
|  |   this->state_ = state; | ||||||
|  |   if (this->restart_cycle_on_state_change_) | ||||||
|  |     this->period_start_time_ = millis(); | ||||||
|  | } | ||||||
|  |  | ||||||
| }  // namespace slow_pwm | }  // namespace slow_pwm | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
| @@ -11,6 +11,10 @@ class SlowPWMOutput : public output::FloatOutput, public Component { | |||||||
|  public: |  public: | ||||||
|   void set_pin(GPIOPin *pin) { pin_ = pin; }; |   void set_pin(GPIOPin *pin) { pin_ = pin; }; | ||||||
|   void set_period(unsigned int period) { period_ = period; }; |   void set_period(unsigned int period) { period_ = period; }; | ||||||
|  |   void set_restart_cycle_on_state_change(bool restart_cycle_on_state_change) { | ||||||
|  |     restart_cycle_on_state_change_ = restart_cycle_on_state_change; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /// Initialize pin |   /// Initialize pin | ||||||
|   void setup() override; |   void setup() override; | ||||||
|   void dump_config() override; |   void dump_config() override; | ||||||
| @@ -37,7 +41,7 @@ class SlowPWMOutput : public output::FloatOutput, public Component { | |||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   void loop() override; |   void loop() override; | ||||||
|   void write_state(float state) override { state_ = state; } |   void write_state(float state) override; | ||||||
|   /// turn on/off the configured output |   /// turn on/off the configured output | ||||||
|   void set_output_state_(bool state); |   void set_output_state_(bool state); | ||||||
|  |  | ||||||
| @@ -48,7 +52,8 @@ class SlowPWMOutput : public output::FloatOutput, public Component { | |||||||
|   float state_{0}; |   float state_{0}; | ||||||
|   bool current_state_{false}; |   bool current_state_{false}; | ||||||
|   unsigned int period_start_time_{0}; |   unsigned int period_start_time_{0}; | ||||||
|   unsigned int period_{5000}; |   unsigned int period_; | ||||||
|  |   bool restart_cycle_on_state_change_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace slow_pwm | }  // namespace slow_pwm | ||||||
|   | |||||||
| @@ -1148,6 +1148,7 @@ output: | |||||||
|     pin: GPIO5 |     pin: GPIO5 | ||||||
|     id: my_slow_pwm |     id: my_slow_pwm | ||||||
|     period: 15s |     period: 15s | ||||||
|  |     restart_cycle_on_state_change: false | ||||||
|   - platform: sm2135 |   - platform: sm2135 | ||||||
|     id: sm2135_0 |     id: sm2135_0 | ||||||
|     channel: 0 |     channel: 0 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user