Add transitions to light flash (#2201)

This commit is contained in:
Alex 2021-08-30 21:18:16 -05:00 committed by GitHub
parent 54337befc2
commit ea1b5e19f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 3 deletions

View file

@ -7,6 +7,7 @@ from esphome.const import (
CONF_DEFAULT_TRANSITION_LENGTH,
CONF_DISABLED_BY_DEFAULT,
CONF_EFFECTS,
CONF_FLASH_TRANSITION_LENGTH,
CONF_GAMMA_CORRECT,
CONF_ID,
CONF_INTERNAL,
@ -85,6 +86,9 @@ BRIGHTNESS_ONLY_LIGHT_SCHEMA = LIGHT_SCHEMA.extend(
cv.Optional(
CONF_DEFAULT_TRANSITION_LENGTH, default="1s"
): cv.positive_time_period_milliseconds,
cv.Optional(
CONF_FLASH_TRANSITION_LENGTH, default="0s"
): cv.positive_time_period_milliseconds,
cv.Optional(CONF_EFFECTS): validate_effects(MONOCHROMATIC_EFFECTS),
}
)
@ -132,6 +136,10 @@ async def setup_light_core_(light_var, output_var, config):
config[CONF_DEFAULT_TRANSITION_LENGTH]
)
)
if CONF_FLASH_TRANSITION_LENGTH in config:
cg.add(
light_var.set_flash_transition_length(config[CONF_FLASH_TRANSITION_LENGTH])
)
if CONF_GAMMA_CORRECT in config:
cg.add(light_var.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
effects = await cg.build_registry_list(

View file

@ -157,6 +157,11 @@ void LightState::add_new_target_state_reached_callback(std::function<void()> &&s
void LightState::set_default_transition_length(uint32_t default_transition_length) {
this->default_transition_length_ = default_transition_length;
}
uint32_t LightState::get_default_transition_length() const { return this->default_transition_length_; }
void LightState::set_flash_transition_length(uint32_t flash_transition_length) {
this->flash_transition_length_ = flash_transition_length;
}
uint32_t LightState::get_flash_transition_length() const { return this->flash_transition_length_; }
void LightState::set_gamma_correct(float gamma_correct) { this->gamma_correct_ = gamma_correct; }
void LightState::set_restore_mode(LightRestoreMode restore_mode) { this->restore_mode_ = restore_mode; }
bool LightState::supports_effects() { return !this->effects_.empty(); }
@ -234,7 +239,7 @@ void LightState::start_flash_(const LightColorValues &target, uint32_t length) {
// If starting a flash if one is already happening, set end values to end values of current flash
// Hacky but works
if (this->transformer_ != nullptr)
end_colors = this->transformer_->get_target_values();
end_colors = this->transformer_->get_start_values();
this->transformer_ = make_unique<LightFlashTransformer>(*this);
this->transformer_->setup(end_colors, target, length);

View file

@ -99,6 +99,11 @@ class LightState : public Nameable, public Component {
/// Set the default transition length, i.e. the transition length when no transition is provided.
void set_default_transition_length(uint32_t default_transition_length);
uint32_t get_default_transition_length() const;
/// Set the flash transition length
void set_flash_transition_length(uint32_t flash_transition_length);
uint32_t get_flash_transition_length() const;
/// Set the gamma correction factor
void set_gamma_correct(float gamma_correct);
@ -188,6 +193,8 @@ class LightState : public Nameable, public Component {
/// Default transition length for all transitions in ms.
uint32_t default_transition_length_{};
/// Transition length to use for flash transitions.
uint32_t flash_transition_length_{};
/// Gamma correction factor for the light.
float gamma_correct_{};
/// Restore mode of the light.

View file

@ -58,7 +58,45 @@ class LightFlashTransformer : public LightTransformer {
public:
LightFlashTransformer(LightState &state) : state_(state) {}
optional<LightColorValues> apply() override { return this->get_target_values(); }
void start() override {
this->transition_length_ = this->state_.get_flash_transition_length();
if (this->transition_length_ * 2 > this->length_)
this->transition_length_ = this->length_ / 2;
// do not create transition if length is 0
if (this->transition_length_ == 0)
return;
// first transition to original target
this->transformer_ = this->state_.get_output()->create_default_transition();
this->transformer_->setup(this->state_.current_values, this->target_values_, this->transition_length_);
}
optional<LightColorValues> apply() override {
// transition transformer does not handle 0 length as progress returns nan
if (this->transition_length_ == 0)
return this->target_values_;
if (this->transformer_ != nullptr) {
if (!this->transformer_->is_finished()) {
return this->transformer_->apply();
} else {
this->transformer_->stop();
this->transformer_ = nullptr;
}
}
if (millis() > this->start_time_ + this->length_ - this->transition_length_ &&
!this->secondary_transition_occurred_) {
// second transition back to start value
this->transformer_ = this->state_.get_output()->create_default_transition();
this->transformer_->setup(this->state_.current_values, this->get_start_values(), this->transition_length_);
this->secondary_transition_occurred_ = true;
}
// once transition is complete, don't change states until next transition
return optional<LightColorValues>();
}
// Restore the original values after the flash.
void stop() override {
@ -69,6 +107,9 @@ class LightFlashTransformer : public LightTransformer {
protected:
LightState &state_;
uint32_t transition_length_;
bool secondary_transition_occurred_{false};
std::unique_ptr<LightTransformer> transformer_{nullptr};
};
} // namespace light

View file

@ -42,7 +42,7 @@ void PowerSupply::request_high_power() {
void PowerSupply::unrequest_high_power() {
this->active_requests_--;
if (this->active_requests_ < 0) {
// we're just going to use 0 as our now counter.
// we're just going to use 0 as our new counter.
this->active_requests_ = 0;
}

View file

@ -241,6 +241,7 @@ CONF_FILTERS = "filters"
CONF_FINGER_ID = "finger_id"
CONF_FINGERPRINT_COUNT = "fingerprint_count"
CONF_FLASH_LENGTH = "flash_length"
CONF_FLASH_TRANSITION_LENGTH = "flash_transition_length"
CONF_FLOW_CONTROL_PIN = "flow_control_pin"
CONF_FOR = "for"
CONF_FORCE_UPDATE = "force_update"