|
@ -15,25 +15,52 @@ namespace bslamp2 { |
|
|
*/ |
|
|
*/ |
|
|
class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTransformer { |
|
|
class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTransformer { |
|
|
public: |
|
|
public: |
|
|
explicit XiaomiBslamp2LightTransitionTransformer(LightHAL *light) : light_(light) { } |
|
|
|
|
|
|
|
|
explicit XiaomiBslamp2LightTransitionTransformer( |
|
|
|
|
|
LightHAL *light, |
|
|
|
|
|
CallbackManager<void(std::string)> light_mode_callback, |
|
|
|
|
|
CallbackManager<void(light::LightColorValues)> state_callback) : |
|
|
|
|
|
light_(light), |
|
|
|
|
|
light_mode_callback_(light_mode_callback), |
|
|
|
|
|
state_callback_(state_callback) { } |
|
|
|
|
|
|
|
|
bool is_finished() override { |
|
|
bool is_finished() override { |
|
|
return force_finish_ || get_progress_() >= 1.0f; |
|
|
return force_finish_ || get_progress_() >= 1.0f; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void start() override { |
|
|
void start() override { |
|
|
// Compute the GPIO outputs to use for the end point. |
|
|
|
|
|
// This light transition transformer will then transition linearly between |
|
|
|
|
|
// the current GPIO outputs and the target ones. |
|
|
|
|
|
|
|
|
// Determine the GPIO outputs to use for the start and end point. |
|
|
|
|
|
// This light transition transformer will then transition linearly between them. |
|
|
light_->copy_to(start_); |
|
|
light_->copy_to(start_); |
|
|
end_->set_light_color_values(target_values_); |
|
|
end_->set_light_color_values(target_values_); |
|
|
|
|
|
|
|
|
|
|
|
// Update the light mode of the light HAL to the target state, unless |
|
|
|
|
|
// this is night mode. For night mode, the update is done after the |
|
|
|
|
|
// state has been reached. This makes sure that forcing instant |
|
|
|
|
|
// transitions for night light to night light is only done when the |
|
|
|
|
|
// night light status has actually been reached. E.g. when in RGB mode |
|
|
|
|
|
// and transitioning to night light in 10 seconds, interrupting this |
|
|
|
|
|
// after 5 seconds with a new night light setting should not make the |
|
|
|
|
|
// transition instant. |
|
|
|
|
|
if (end_->light_mode != LIGHT_MODE_NIGHT) { |
|
|
|
|
|
light_->set_light_mode(end_->light_mode); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Run callbacks. These are normally called from the LightOutput, but |
|
|
|
|
|
// since I don't call LightOutput::write_state() from this transformer's |
|
|
|
|
|
// code, these callbacks must be called from this transformer instead. |
|
|
|
|
|
light_mode_callback_.call(end_->light_mode); |
|
|
|
|
|
state_callback_.call(target_values_); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
optional<light::LightColorValues> apply() override { |
|
|
optional<light::LightColorValues> apply() override { |
|
|
if (end_->light_mode == "night") { |
|
|
|
|
|
|
|
|
// When transitioning between night mode light colors, then do this immediately. |
|
|
|
|
|
// The LED driver circuitry is not capable of doing clean color or brightness |
|
|
|
|
|
// transitions at the low levels as used for the night light. |
|
|
|
|
|
if (end_->light_mode == LIGHT_MODE_NIGHT && start_->light_mode == LIGHT_MODE_NIGHT) { |
|
|
light_->set_state(end_); |
|
|
light_->set_state(end_); |
|
|
force_finish_ = true; |
|
|
force_finish_ = true; |
|
|
} |
|
|
} |
|
|
|
|
|
// Otherwise perform a standard transformation. |
|
|
else { |
|
|
else { |
|
|
auto smoothed = light::LightTransitionTransformer::smoothed_progress(get_progress_()); |
|
|
auto smoothed = light::LightTransitionTransformer::smoothed_progress(get_progress_()); |
|
|
light_->set_rgbw( |
|
|
light_->set_rgbw( |
|
@ -41,9 +68,17 @@ class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTra |
|
|
esphome::lerp(smoothed, start_->green, end_->green), |
|
|
esphome::lerp(smoothed, start_->green, end_->green), |
|
|
esphome::lerp(smoothed, start_->blue, end_->blue), |
|
|
esphome::lerp(smoothed, start_->blue, end_->blue), |
|
|
esphome::lerp(smoothed, start_->white, end_->white)); |
|
|
esphome::lerp(smoothed, start_->white, end_->white)); |
|
|
|
|
|
if (end_->light_mode != LIGHT_MODE_OFF) { |
|
|
|
|
|
light_->turn_on(); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (is_finished()) { |
|
|
if (is_finished()) { |
|
|
|
|
|
light_->set_light_mode(end_->light_mode); |
|
|
|
|
|
if (end_->light_mode == LIGHT_MODE_OFF) { |
|
|
|
|
|
light_->turn_off(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return target_values_; |
|
|
return target_values_; |
|
|
} else { |
|
|
} else { |
|
|
return {}; |
|
|
return {}; |
|
@ -52,9 +87,11 @@ class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTra |
|
|
|
|
|
|
|
|
protected: |
|
|
protected: |
|
|
LightHAL *light_; |
|
|
LightHAL *light_; |
|
|
bool force_finish_ = false; |
|
|
|
|
|
|
|
|
bool force_finish_{false}; |
|
|
GPIOOutputValues *start_ = new GPIOOutputValues(); |
|
|
GPIOOutputValues *start_ = new GPIOOutputValues(); |
|
|
ColorHandler *end_ = new ColorHandlerChain(); |
|
|
ColorHandler *end_ = new ColorHandlerChain(); |
|
|
|
|
|
CallbackManager<void(std::string)> light_mode_callback_{}; |
|
|
|
|
|
CallbackManager<void(light::LightColorValues)> state_callback_{}; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
} // namespace bslamp2 |
|
|
} // namespace bslamp2 |
|
|