- #pragma once
-
- #include "../common.h"
- #include "../light_hal.h"
- #include "color_handler_chain.h"
- #include "esphome/components/light/light_transformer.h"
- #include "esphome/components/light/light_color_values.h"
-
- namespace esphome {
- namespace xiaomi {
- namespace bslamp2 {
-
- /**
- * A LightTransitionTransformer class for the Xiaomi Mijia Bedside Lamp 2.
- */
- class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTransformer {
- public:
- 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 {
- return force_finish_ || get_progress_() >= 1.0f;
- }
-
- void start() override {
- // 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_);
- 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 {
- // 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_);
- force_finish_ = true;
- }
- // Otherwise perform a standard transformation.
- else {
- auto smoothed = light::LightTransitionTransformer::smoothed_progress(get_progress_());
- light_->set_rgbw(
- esphome::lerp(smoothed, start_.red, end_.red),
- esphome::lerp(smoothed, start_.green, end_.green),
- esphome::lerp(smoothed, start_.blue, end_.blue),
- esphome::lerp(smoothed, start_.white, end_.white));
- if (end_.light_mode != LIGHT_MODE_OFF) {
- light_->turn_on();
- }
- }
-
- if (is_finished()) {
- light_->set_light_mode(end_.light_mode);
- if (end_.light_mode == LIGHT_MODE_OFF) {
- light_->turn_off();
- }
-
- return target_values_;
- } else {
- return {};
- }
- }
-
- protected:
- LightHAL *light_;
- bool force_finish_{false};
- GPIOOutputValues start_{};
- ColorHandlerChain end_{};
- CallbackManager<void(std::string)> light_mode_callback_{};
- CallbackManager<void(light::LightColorValues)> state_callback_{};
- };
-
- } // namespace bslamp2
- } // namespace xiaomi
- } // namespace esphome
|