mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Light transition fixes (#2320)
This commit is contained in:
		
				
					committed by
					
						 Jesse Hills
						Jesse Hills
					
				
			
			
				
	
			
			
			
						parent
						
							c78fb90e2f
						
					
				
				
					commit
					4c61cf153c
				
			| @@ -62,10 +62,13 @@ void AddressableLightTransformer::start() { | ||||
| } | ||||
|  | ||||
| optional<LightColorValues> AddressableLightTransformer::apply() { | ||||
|   // Don't try to transition over running effects, instead immediately use the target values. write_state() and the | ||||
|   // effects pick up the change from current_values. | ||||
|   float smoothed_progress = LightTransitionTransformer::smoothed_progress(this->get_progress_()); | ||||
|  | ||||
|   // When running an output-buffer modifying effect, don't try to transition individual LEDs, but instead just fade the | ||||
|   // LightColorValues. write_state() then picks up the change in brightness, and the color change is picked up by the | ||||
|   // effects which respect it. | ||||
|   if (this->light_.is_effect_active()) | ||||
|     return this->target_values_; | ||||
|     return LightColorValues::lerp(this->get_start_values(), this->get_target_values(), smoothed_progress); | ||||
|  | ||||
|   // Use a specialized transition for addressable lights: instead of using a unified transition for | ||||
|   // all LEDs, we use the current state of each LED as the start. | ||||
| @@ -75,8 +78,6 @@ optional<LightColorValues> AddressableLightTransformer::apply() { | ||||
|   // Instead, we "fake" the look of the LERP by using an exponential average over time and using | ||||
|   // dynamically-calculated alpha values to match the look. | ||||
|  | ||||
|   float smoothed_progress = LightTransitionTransformer::smoothed_progress(this->get_progress_()); | ||||
|  | ||||
|   float denom = (1.0f - smoothed_progress); | ||||
|   float alpha = denom == 0.0f ? 0.0f : (smoothed_progress - this->last_transition_progress_) / denom; | ||||
|  | ||||
|   | ||||
| @@ -121,6 +121,9 @@ void LightState::loop() { | ||||
|     } | ||||
|  | ||||
|     if (this->transformer_->is_finished()) { | ||||
|       // if the transition has written directly to the output, current_values is outdated, so update it | ||||
|       this->current_values = this->transformer_->get_target_values(); | ||||
|  | ||||
|       this->transformer_->stop(); | ||||
|       this->transformer_ = nullptr; | ||||
|       this->target_state_reached_callback_.call(); | ||||
|   | ||||
| @@ -12,12 +12,18 @@ namespace light { | ||||
| class LightTransitionTransformer : public LightTransformer { | ||||
|  public: | ||||
|   void start() override { | ||||
|     // When turning light on from off state, use colors from target state. | ||||
|     // When turning light on from off state, use target state and only increase brightness from zero. | ||||
|     if (!this->start_values_.is_on() && this->target_values_.is_on()) { | ||||
|       this->start_values_ = LightColorValues(this->target_values_); | ||||
|       this->start_values_.set_brightness(0.0f); | ||||
|     } | ||||
|  | ||||
|     // When turning light off from on state, use source state and only decrease brightness to zero. | ||||
|     if (this->start_values_.is_on() && !this->target_values_.is_on()) { | ||||
|       this->target_values_ = LightColorValues(this->start_values_); | ||||
|       this->target_values_.set_brightness(0.0f); | ||||
|     } | ||||
|  | ||||
|     // When changing color mode, go through off state, as color modes are orthogonal and there can't be two active. | ||||
|     if (this->start_values_.get_color_mode() != this->target_values_.get_color_mode()) { | ||||
|       this->changing_color_mode_ = true; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user