Compare commits

...

Author SHA1 Message Date
  Maurice Makaay a8dc0b6dab Code cleanup. 3 years ago
  Maurice Makaay 350d10b912 Made the code compatible with @oxan 's light-transformation branch. 3 years ago
12 changed files with 139 additions and 116 deletions
Unified View
  1. +0
    -1
      components/xiaomi_bslamp2/__init__.py
  2. +4
    -4
      components/xiaomi_bslamp2/binary_sensor/__init__.py
  3. +63
    -44
      components/xiaomi_bslamp2/light/__init__.py
  4. +3
    -2
      components/xiaomi_bslamp2/light/automation.h
  5. +3
    -18
      components/xiaomi_bslamp2/light/light_output.h
  6. +22
    -22
      components/xiaomi_bslamp2/light/light_transition.h
  7. +7
    -7
      components/xiaomi_bslamp2/light/presets.h
  8. +18
    -0
      components/xiaomi_bslamp2/light_hal.h
  9. +4
    -4
      components/xiaomi_bslamp2/output/__init__.py
  10. +4
    -4
      components/xiaomi_bslamp2/sensor/__init__.py
  11. +8
    -8
      components/xiaomi_bslamp2/text_sensor/__init__.py
  12. +3
    -2
      components/xiaomi_bslamp2/text_sensor/light_mode_text_sensor.h

+ 0
- 1
components/xiaomi_bslamp2/__init__.py View File

@ -4,7 +4,6 @@ from esphome import pins
from esphome.components.ledc.output import LEDCOutput from esphome.components.ledc.output import LEDCOutput
from esphome.components.gpio.output import GPIOBinaryOutput from esphome.components.gpio.output import GPIOBinaryOutput
from esphome.components.i2c import I2CComponent, I2CDevice from esphome.components.i2c import I2CComponent, I2CDevice
from esphome.core import coroutine
from esphome.core import CORE from esphome.core import CORE
from esphome.const import ( from esphome.const import (
CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, CONF_TRIGGER_PIN, CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, CONF_TRIGGER_PIN,


+ 4
- 4
components/xiaomi_bslamp2/binary_sensor/__init__.py View File

@ -54,11 +54,11 @@ CONFIG_SCHEMA = cv.All(
validate_binary_sensor, validate_binary_sensor,
) )
def to_code(config):
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
yield binary_sensor.register_binary_sensor(var, config)
await cg.register_component(var, config)
await binary_sensor.register_binary_sensor(var, config)
front_panel_hal_var = yield cg.get_variable(config[CONF_FRONT_PANEL_HAL_ID])
front_panel_hal_var = await cg.get_variable(config[CONF_FRONT_PANEL_HAL_ID])
cg.add(var.set_parent(front_panel_hal_var)) cg.add(var.set_parent(front_panel_hal_var))
cg.add(var.set_for(config[CONF_FOR])) cg.add(var.set_for(config[CONF_FOR]))

+ 63
- 44
components/xiaomi_bslamp2/light/__init__.py View File

@ -2,11 +2,12 @@ import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import light from esphome.components import light
from esphome import automation from esphome import automation
from esphome.core import coroutine, Lambda
from esphome.core import Lambda
from esphome.const import ( from esphome.const import (
CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, CONF_COLOR_TEMPERATURE, CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, CONF_COLOR_TEMPERATURE,
CONF_STATE, CONF_OUTPUT_ID, CONF_TRIGGER_ID, CONF_ID, CONF_STATE, CONF_OUTPUT_ID, CONF_TRIGGER_ID, CONF_ID,
CONF_TRANSITION_LENGTH, CONF_BRIGHTNESS, CONF_EFFECT, CONF_FLASH_LENGTH
CONF_TRANSITION_LENGTH, CONF_BRIGHTNESS, CONF_EFFECT, CONF_FLASH_LENGTH,
CONF_TRANSITIONS, CONF_NAME
) )
from .. import bslamp2_ns, CODEOWNERS, CONF_LIGHT_HAL_ID, LightHAL from .. import bslamp2_ns, CODEOWNERS, CONF_LIGHT_HAL_ID, LightHAL
@ -27,11 +28,13 @@ MIRED_MAX = 588
XiaomiBslamp2LightState = bslamp2_ns.class_("XiaomiBslamp2LightState", light.LightState) XiaomiBslamp2LightState = bslamp2_ns.class_("XiaomiBslamp2LightState", light.LightState)
XiaomiBslamp2LightOutput = bslamp2_ns.class_("XiaomiBslamp2LightOutput", light.LightOutput) XiaomiBslamp2LightOutput = bslamp2_ns.class_("XiaomiBslamp2LightOutput", light.LightOutput)
XiaomiBslamp2LightTransition = bslamp2_ns.class_("XiaomiBslamp2LightTransition", light.LightTransition)
PresetsContainer = bslamp2_ns.class_("PresetsContainer", cg.Component) PresetsContainer = bslamp2_ns.class_("PresetsContainer", cg.Component)
Preset = bslamp2_ns.class_("Preset", cg.Component) Preset = bslamp2_ns.class_("Preset", cg.Component)
BrightnessTrigger = bslamp2_ns.class_("BrightnessTrigger", automation.Trigger.template()) BrightnessTrigger = bslamp2_ns.class_("BrightnessTrigger", automation.Trigger.template())
ActivatePresetAction = bslamp2_ns.class_("ActivatePresetAction", automation.Action) ActivatePresetAction = bslamp2_ns.class_("ActivatePresetAction", automation.Action)
DiscoAction = bslamp2_ns.class_("DiscoAction", automation.Action) DiscoAction = bslamp2_ns.class_("DiscoAction", automation.Action)
DiscoAction = bslamp2_ns.class_("DiscoAction", automation.Action)
PRESETS_SCHEMA = cv.Schema({ PRESETS_SCHEMA = cv.Schema({
str.lower: cv.Schema({ str.lower: cv.Schema({
@ -86,6 +89,9 @@ CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend(
cv.GenerateID(CONF_ID): cv.declare_id(XiaomiBslamp2LightState), cv.GenerateID(CONF_ID): cv.declare_id(XiaomiBslamp2LightState),
cv.GenerateID(CONF_LIGHT_HAL_ID): cv.use_id(LightHAL), cv.GenerateID(CONF_LIGHT_HAL_ID): cv.use_id(LightHAL),
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(XiaomiBslamp2LightOutput), cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(XiaomiBslamp2LightOutput),
cv.Optional(
CONF_TRANSITIONS, default=["bslamp2"]
): light.transitions.validate_transitions(XiaomiBslamp2LightOutput),
cv.Optional(CONF_ON_BRIGHTNESS): automation.validate_automation( cv.Optional(CONF_ON_BRIGHTNESS): automation.validate_automation(
{ {
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(BrightnessTrigger), cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(BrightnessTrigger),
@ -129,49 +135,49 @@ def maybe_simple_preset_action(schema):
@automation.register_action( @automation.register_action(
"light.disco_on", DiscoAction, light.automation.LIGHT_TURN_ON_ACTION_SCHEMA "light.disco_on", DiscoAction, light.automation.LIGHT_TURN_ON_ACTION_SCHEMA
) )
def disco_action_on_to_code(config, action_id, template_arg, args):
light_var = yield cg.get_variable(config[CONF_ID])
async def disco_action_on_to_code(config, action_id, template_arg, args):
light_var = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, light_var) var = cg.new_Pvariable(action_id, template_arg, light_var)
if CONF_STATE in config: if CONF_STATE in config:
template_ = yield cg.templatable(config[CONF_STATE], args, bool)
template_ = await cg.templatable(config[CONF_STATE], args, bool)
cg.add(var.set_state(template_)) cg.add(var.set_state(template_))
if CONF_TRANSITION_LENGTH in config: if CONF_TRANSITION_LENGTH in config:
template_ = yield cg.templatable(
template_ = await cg.templatable(
config[CONF_TRANSITION_LENGTH], args, cg.uint32 config[CONF_TRANSITION_LENGTH], args, cg.uint32
) )
cg.add(var.set_transition_length(template_)) cg.add(var.set_transition_length(template_))
if CONF_FLASH_LENGTH in config: if CONF_FLASH_LENGTH in config:
template_ = yield cg.templatable(config[CONF_FLASH_LENGTH], args, cg.uint32)
template_ = await cg.templatable(config[CONF_FLASH_LENGTH], args, cg.uint32)
cg.add(var.set_flash_length(template_)) cg.add(var.set_flash_length(template_))
if CONF_BRIGHTNESS in config: if CONF_BRIGHTNESS in config:
template_ = yield cg.templatable(config[CONF_BRIGHTNESS], args, float)
template_ = await cg.templatable(config[CONF_BRIGHTNESS], args, float)
cg.add(var.set_brightness(template_)) cg.add(var.set_brightness(template_))
if CONF_RED in config: if CONF_RED in config:
template_ = yield cg.templatable(config[CONF_RED], args, float)
template_ = await cg.templatable(config[CONF_RED], args, float)
cg.add(var.set_red(template_)) cg.add(var.set_red(template_))
if CONF_GREEN in config: if CONF_GREEN in config:
template_ = yield cg.templatable(config[CONF_GREEN], args, float)
template_ = await cg.templatable(config[CONF_GREEN], args, float)
cg.add(var.set_green(template_)) cg.add(var.set_green(template_))
if CONF_BLUE in config: if CONF_BLUE in config:
template_ = yield cg.templatable(config[CONF_BLUE], args, float)
template_ = await cg.templatable(config[CONF_BLUE], args, float)
cg.add(var.set_blue(template_)) cg.add(var.set_blue(template_))
if CONF_COLOR_TEMPERATURE in config: if CONF_COLOR_TEMPERATURE in config:
template_ = yield cg.templatable(config[CONF_COLOR_TEMPERATURE], args, float)
template_ = await cg.templatable(config[CONF_COLOR_TEMPERATURE], args, float)
cg.add(var.set_color_temperature(template_)) cg.add(var.set_color_temperature(template_))
if CONF_EFFECT in config: if CONF_EFFECT in config:
template_ = yield cg.templatable(config[CONF_EFFECT], args, cg.std_string)
template_ = await cg.templatable(config[CONF_EFFECT], args, cg.std_string)
cg.add(var.set_effect(template_)) cg.add(var.set_effect(template_))
yield var
return var
@automation.register_action( @automation.register_action(
"light.disco_off", DiscoAction, light.automation.LIGHT_TURN_OFF_ACTION_SCHEMA "light.disco_off", DiscoAction, light.automation.LIGHT_TURN_OFF_ACTION_SCHEMA
) )
def disco_action_off_to_code(config, action_id, template_arg, args):
light_var = yield cg.get_variable(config[CONF_ID])
async def disco_action_off_to_code(config, action_id, template_arg, args):
light_var = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, light_var) var = cg.new_Pvariable(action_id, template_arg, light_var)
cg.add(var.set_disco_state(False)) cg.add(var.set_disco_state(False))
yield var
return var
USED_PRESETS = [] USED_PRESETS = []
@ -202,40 +208,54 @@ def register_preset_action(value):
register_preset_action register_preset_action
), ),
) )
def preset_activate_to_code(config, action_id, template_arg, args):
presets_var = yield cg.get_variable(config[CONF_PRESETS_ID])
async def preset_activate_to_code(config, action_id, template_arg, args):
presets_var = await cg.get_variable(config[CONF_PRESETS_ID])
action_var = cg.new_Pvariable(action_id, template_arg, presets_var) action_var = cg.new_Pvariable(action_id, template_arg, presets_var)
if CONF_NEXT in config: if CONF_NEXT in config:
cg.add(action_var.set_operation(f"next_{config[CONF_NEXT]}")) cg.add(action_var.set_operation(f"next_{config[CONF_NEXT]}"))
elif CONF_PRESET in config: elif CONF_PRESET in config:
cg.add(action_var.set_operation("activate_preset")) cg.add(action_var.set_operation("activate_preset"))
group_template_ = yield cg.templatable(config[CONF_GROUP], args, cg.std_string)
group_template_ = await cg.templatable(config[CONF_GROUP], args, cg.std_string)
cg.add(action_var.set_group(group_template_)) cg.add(action_var.set_group(group_template_))
preset_template_ = yield cg.templatable(config[CONF_PRESET], args, cg.std_string)
preset_template_ = await cg.templatable(config[CONF_PRESET], args, cg.std_string)
cg.add(action_var.set_preset(preset_template_)) cg.add(action_var.set_preset(preset_template_))
else: else:
cg.add(action_var.set_operation("activate_group")) cg.add(action_var.set_operation("activate_group"))
group_template_ = yield cg.templatable(config[CONF_GROUP], args, cg.std_string)
group_template_ = await cg.templatable(config[CONF_GROUP], args, cg.std_string)
cg.add(action_var.set_group(group_template_)) cg.add(action_var.set_group(group_template_))
yield action_var
return action_var
@light.transitions.register_output_transition(
XiaomiBslamp2LightOutput,
"bslamp2",
XiaomiBslamp2LightTransition,
"bslamp2",
{
cv.GenerateID(CONF_LIGHT_HAL_ID): cv.use_id(LightHAL),
},
)
async def bslamp2_transition_to_code(config, transition_id):
light_hal_var = await cg.get_variable(config[CONF_LIGHT_HAL_ID])
return cg.new_Pvariable(
transition_id,
config[CONF_NAME],
light_hal_var
)
@coroutine
def light_output_to_code(config):
async def light_output_to_code(config):
light_output_var = cg.new_Pvariable(config[CONF_OUTPUT_ID]) light_output_var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
yield light.register_light(light_output_var, config)
light_hal_var = yield cg.get_variable(config[CONF_LIGHT_HAL_ID])
await light.register_light(light_output_var, config)
light_hal_var = await cg.get_variable(config[CONF_LIGHT_HAL_ID])
cg.add(light_output_var.set_parent(light_hal_var)) cg.add(light_output_var.set_parent(light_hal_var))
@coroutine
def on_brightness_to_code(config):
light_output_var = yield cg.get_variable(config[CONF_OUTPUT_ID])
async def on_brightness_to_code(config):
light_hal_var = await cg.get_variable(config[CONF_LIGHT_HAL_ID])
for config in config.get(CONF_ON_BRIGHTNESS, []): for config in config.get(CONF_ON_BRIGHTNESS, []):
trigger = cg.new_Pvariable(config[CONF_TRIGGER_ID], light_output_var)
yield automation.build_automation(trigger, [(float, "x")], config)
trigger = cg.new_Pvariable(config[CONF_TRIGGER_ID], light_hal_var)
await automation.build_automation(trigger, [(float, "x")], config)
@coroutine
def preset_to_code(config, preset_group, preset_name):
light_var = yield cg.get_variable(config[CONF_ID])
async def preset_to_code(config, preset_group, preset_name):
light_var = await cg.get_variable(config[CONF_ID])
preset_var = cg.new_Pvariable( preset_var = cg.new_Pvariable(
config[CONF_PRESET_ID], light_var, preset_group, preset_name) config[CONF_PRESET_ID], light_var, preset_group, preset_name)
if CONF_TRANSITION_LENGTH in config: if CONF_TRANSITION_LENGTH in config:
@ -254,22 +274,21 @@ def preset_to_code(config, preset_group, preset_name):
cg.add(preset_var.set_effect(config[CONF_EFFECT])) cg.add(preset_var.set_effect(config[CONF_EFFECT]))
else: else:
cg.add(preset_var.set_effect("None")) cg.add(preset_var.set_effect("None"))
yield cg.register_component(preset_var, config)
return await cg.register_component(preset_var, config)
@coroutine
def presets_to_code(config):
async def presets_to_code(config):
presets_var = cg.new_Pvariable(config[CONF_PRESETS_ID]) presets_var = cg.new_Pvariable(config[CONF_PRESETS_ID])
yield cg.register_component(presets_var, config)
await cg.register_component(presets_var, config)
for preset_group, presets in config.get(CONF_PRESETS, {}).items(): for preset_group, presets in config.get(CONF_PRESETS, {}).items():
for preset_name, preset_config in presets.items(): for preset_name, preset_config in presets.items():
preset = yield preset_to_code(preset_config, preset_group, preset_name)
preset = await preset_to_code(preset_config, preset_group, preset_name)
cg.add(presets_var.add_preset(preset)) cg.add(presets_var.add_preset(preset))
def to_code(config):
yield light_output_to_code(config)
yield on_brightness_to_code(config)
yield presets_to_code(config)
async def to_code(config):
await light_output_to_code(config)
await on_brightness_to_code(config)
await presets_to_code(config)
def validate(config): def validate(config):
valid_presets = config.get(CONF_PRESETS, {}); valid_presets = config.get(CONF_PRESETS, {});


+ 3
- 2
components/xiaomi_bslamp2/light/automation.h View File

@ -3,6 +3,7 @@
#include "esphome/core/automation.h" #include "esphome/core/automation.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "interfaces.h" #include "interfaces.h"
#include "../light_hal.h"
#include "light_output.h" #include "light_output.h"
#include "light_state.h" #include "light_state.h"
#include "presets.h" #include "presets.h"
@ -14,7 +15,7 @@ namespace bslamp2 {
class BrightnessTrigger : public Trigger<float> { class BrightnessTrigger : public Trigger<float> {
public: public:
explicit BrightnessTrigger(XiaomiBslamp2LightOutput *parent) {
explicit BrightnessTrigger(LightHAL *parent) {
parent->add_on_state_callback([this](light::LightColorValues values) { parent->add_on_state_callback([this](light::LightColorValues values) {
auto new_brightness = values.get_brightness(); auto new_brightness = values.get_brightness();
if (values.get_state() == 0) if (values.get_state() == 0)
@ -28,7 +29,7 @@ class BrightnessTrigger : public Trigger<float> {
} }
protected: protected:
float last_brightness_ = -1.0f;
float last_brightness_{-1.0f};
}; };
template<typename... Ts> class DiscoAction : public Action<Ts...> { template<typename... Ts> class DiscoAction : public Action<Ts...> {


+ 3
- 18
components/xiaomi_bslamp2/light/light_output.h View File

@ -3,7 +3,7 @@
#include "../common.h" #include "../common.h"
#include "../light_hal.h" #include "../light_hal.h"
#include "color_handler_chain.h" #include "color_handler_chain.h"
#include "light_transformer.h"
#include "light_transition.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/components/ledc/ledc_output.h" #include "esphome/components/ledc/ledc_output.h"
@ -35,19 +35,6 @@ class XiaomiBslamp2LightOutput : public Component, public light::LightOutput {
return traits; return traits;
} }
std::unique_ptr<light::LightTransformer> create_default_transition() override {
return make_unique<XiaomiBslamp2LightTransitionTransformer>(
light_, light_mode_callback_, state_callback_);
}
void add_on_light_mode_callback(std::function<void(std::string)> &&callback) {
light_mode_callback_.add(std::move(callback));
}
void add_on_state_callback(std::function<void(light::LightColorValues)> &&callback) {
state_callback_.add(std::move(callback));
}
/** /**
* Applies a requested light state to the physicial GPIO outputs. * Applies a requested light state to the physicial GPIO outputs.
*/ */
@ -55,8 +42,8 @@ class XiaomiBslamp2LightOutput : public Component, public light::LightOutput {
auto values = state->current_values; auto values = state->current_values;
color_handler_chain->set_light_color_values(values); color_handler_chain->set_light_color_values(values);
light_mode_callback_.call(color_handler_chain->light_mode);
state_callback_.call(values);
light_->do_light_mode_callback(color_handler_chain->light_mode);
light_->do_state_callback(values);
// Note: one might think that it is more logical to turn on the LED // Note: one might think that it is more logical to turn on the LED
// circuitry master switch after setting the individual channels, // circuitry master switch after setting the individual channels,
@ -76,8 +63,6 @@ class XiaomiBslamp2LightOutput : public Component, public light::LightOutput {
protected: protected:
LightHAL *light_; LightHAL *light_;
ColorHandler *color_handler_chain = new ColorHandlerChain(); ColorHandler *color_handler_chain = new ColorHandlerChain();
CallbackManager<void(std::string)> light_mode_callback_{};
CallbackManager<void(light::LightColorValues)> state_callback_{};
}; };
} // namespace bslamp2 } // namespace bslamp2


components/xiaomi_bslamp2/light/light_transformer.h → components/xiaomi_bslamp2/light/light_transition.h View File

@ -3,7 +3,8 @@
#include "../common.h" #include "../common.h"
#include "../light_hal.h" #include "../light_hal.h"
#include "color_handler_chain.h" #include "color_handler_chain.h"
#include "esphome/components/light/light_transformer.h"
#include "esphome/components/light/light_transition.h"
#include "esphome/components/light/transitions.h"
#include "esphome/components/light/light_color_values.h" #include "esphome/components/light/light_color_values.h"
namespace esphome { namespace esphome {
@ -11,20 +12,16 @@ namespace xiaomi {
namespace bslamp2 { namespace bslamp2 {
/** /**
* A LightTransitionTransformer class for the Xiaomi Mijia Bedside Lamp 2.
* A LightTransition class for the Xiaomi Mijia Bedside Lamp 2.
*/ */
class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTransformer {
class XiaomiBslamp2LightTransition : public light::LightTransition {
public: 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) { }
explicit XiaomiBslamp2LightTransition(std::string name, LightHAL *light) :
light::LightTransition(name),
light_(light) { }
bool is_finished() override {
return force_finish_ || get_progress_() >= 1.0f;
bool is_completed() override {
return force_completed_ || get_progress_() >= 1.0f;
} }
void start() override { void start() override {
@ -47,9 +44,9 @@ class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTra
// Run callbacks. These are normally called from the LightOutput, but // Run callbacks. These are normally called from the LightOutput, but
// since I don't call LightOutput::write_state() from this transformer's // 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_);
// code, these callbacks must be called from this transformer as well.
light_->do_light_mode_callback(end_->light_mode);
light_->do_state_callback(target_values_);
} }
optional<light::LightColorValues> apply() override { optional<light::LightColorValues> apply() override {
@ -58,11 +55,11 @@ class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTra
// transitions at the low levels as used for the night light. // transitions at the low levels as used for the night light.
if (end_->light_mode == LIGHT_MODE_NIGHT && start_->light_mode == LIGHT_MODE_NIGHT) { 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_completed_ = true;
} }
// Otherwise perform a standard transformation.
// Otherwise perform a standard transition.
else { else {
auto smoothed = light::LightTransitionTransformer::smoothed_progress(get_progress_());
auto smoothed = smoothed_progress_(get_progress_());
light_->set_rgbw( light_->set_rgbw(
esphome::lerp(smoothed, start_->red, end_->red), esphome::lerp(smoothed, start_->red, end_->red),
esphome::lerp(smoothed, start_->green, end_->green), esphome::lerp(smoothed, start_->green, end_->green),
@ -73,7 +70,7 @@ class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTra
} }
} }
if (is_finished()) {
if (is_completed()) {
light_->set_light_mode(end_->light_mode); light_->set_light_mode(end_->light_mode);
if (end_->light_mode == LIGHT_MODE_OFF) { if (end_->light_mode == LIGHT_MODE_OFF) {
light_->turn_off(); light_->turn_off();
@ -87,11 +84,14 @@ class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTra
protected: protected:
LightHAL *light_; LightHAL *light_;
bool force_finish_{false};
bool force_completed_{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_{};
protected:
static float smoothed_progress_(float x) {
return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f);
}
}; };
} // namespace bslamp2 } // namespace bslamp2

+ 7
- 7
components/xiaomi_bslamp2/light/presets.h View File

@ -47,13 +47,13 @@ class Preset : public Component {
protected: protected:
light::LightState *light_state_; light::LightState *light_state_;
optional<uint32_t> transition_length_;
optional<float> brightness_;
optional<float> red_;
optional<float> green_;
optional<float> blue_;
optional<float> color_temperature_;
optional<std::string> effect_;
optional<uint32_t> transition_length_{};
optional<float> brightness_{};
optional<float> red_{};
optional<float> green_{};
optional<float> blue_{};
optional<float> color_temperature_{};
optional<std::string> effect_{};
}; };
class PresetGroup { class PresetGroup {


+ 18
- 0
components/xiaomi_bslamp2/light_hal.h View File

@ -45,6 +45,14 @@ class LightHAL : Component, public GPIOOutputValues {
void set_master1_pin(gpio::GPIOBinaryOutput *pin) { master1_pin_ = pin; } void set_master1_pin(gpio::GPIOBinaryOutput *pin) { master1_pin_ = pin; }
void set_master2_pin(gpio::GPIOBinaryOutput *pin) { master2_pin_ = pin; } void set_master2_pin(gpio::GPIOBinaryOutput *pin) { master2_pin_ = pin; }
void add_on_light_mode_callback(std::function<void(std::string)> &&callback) {
light_mode_callback_.add(std::move(callback));
}
void add_on_state_callback(std::function<void(light::LightColorValues)> &&callback) {
state_callback_.add(std::move(callback));
}
/** /**
* Turn on the master switch for the LEDs. * Turn on the master switch for the LEDs.
*/ */
@ -94,6 +102,14 @@ class LightHAL : Component, public GPIOOutputValues {
this->light_mode = light_mode; this->light_mode = light_mode;
} }
void do_light_mode_callback(std::string light_mode) {
light_mode_callback_.call(light_mode);
}
void do_state_callback(light::LightColorValues values) {
state_callback_.call(values);
}
protected: protected:
bool is_on_{false}; bool is_on_{false};
ledc::LEDCOutput *red_pin_; ledc::LEDCOutput *red_pin_;
@ -102,6 +118,8 @@ class LightHAL : Component, public GPIOOutputValues {
ledc::LEDCOutput *white_pin_; ledc::LEDCOutput *white_pin_;
gpio::GPIOBinaryOutput *master1_pin_; gpio::GPIOBinaryOutput *master1_pin_;
gpio::GPIOBinaryOutput *master2_pin_; gpio::GPIOBinaryOutput *master2_pin_;
CallbackManager<void(std::string)> light_mode_callback_{};
CallbackManager<void(light::LightColorValues)> state_callback_{};
}; };
} // namespace bslamp2 } // namespace bslamp2


+ 4
- 4
components/xiaomi_bslamp2/output/__init__.py View File

@ -24,12 +24,12 @@ CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
} }
).extend(cv.COMPONENT_SCHEMA) ).extend(cv.COMPONENT_SCHEMA)
def to_code(config):
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
yield output.register_output(var, config)
await cg.register_component(var, config)
await output.register_output(var, config)
front_panel_hal_var = yield cg.get_variable(config[CONF_FRONT_PANEL_HAL_ID])
front_panel_hal_var = await cg.get_variable(config[CONF_FRONT_PANEL_HAL_ID])
cg.add(var.set_parent(front_panel_hal_var)) cg.add(var.set_parent(front_panel_hal_var))
def maybe_simple_level_value(schema): def maybe_simple_level_value(schema):


+ 4
- 4
components/xiaomi_bslamp2/sensor/__init__.py View File

@ -22,12 +22,12 @@ CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend(
} }
).extend(cv.COMPONENT_SCHEMA) ).extend(cv.COMPONENT_SCHEMA)
def to_code(config):
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
yield sensor.register_sensor(var, config)
await cg.register_component(var, config)
await sensor.register_sensor(var, config)
front_panel_hal_var = yield cg.get_variable(config[CONF_FRONT_PANEL_HAL_ID])
front_panel_hal_var = await cg.get_variable(config[CONF_FRONT_PANEL_HAL_ID])
cg.add(var.set_parent(front_panel_hal_var)) cg.add(var.set_parent(front_panel_hal_var))
cg.add(var.set_range_from(config[CONF_RANGE_FROM])) cg.add(var.set_range_from(config[CONF_RANGE_FROM]))
cg.add(var.set_range_to(config[CONF_RANGE_TO])) cg.add(var.set_range_to(config[CONF_RANGE_TO]))

+ 8
- 8
components/xiaomi_bslamp2/text_sensor/__init__.py View File

@ -1,9 +1,9 @@
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import text_sensor from esphome.components import text_sensor
from esphome.const import CONF_ID, CONF_OUTPUT_ID
from .. import bslamp2_ns, CODEOWNERS
from ..light import XiaomiBslamp2LightOutput
from esphome.const import CONF_ID
from .. import bslamp2_ns, CODEOWNERS, CONF_LIGHT_HAL_ID
from ..light import LightHAL
DEPENDENCIES = ["xiaomi_bslamp2"] DEPENDENCIES = ["xiaomi_bslamp2"]
@ -16,15 +16,15 @@ XiaomiBslamp2LightModeTextSensor = bslamp2_ns.class_(
CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend( CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend(
{ {
cv.GenerateID(): cv.declare_id(XiaomiBslamp2LightModeTextSensor), cv.GenerateID(): cv.declare_id(XiaomiBslamp2LightModeTextSensor),
cv.GenerateID(CONF_OUTPUT_ID): cv.use_id(XiaomiBslamp2LightOutput),
cv.GenerateID(CONF_LIGHT_HAL_ID): cv.use_id(LightHAL),
} }
).extend(cv.COMPONENT_SCHEMA) ).extend(cv.COMPONENT_SCHEMA)
def to_code(config):
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
yield text_sensor.register_text_sensor(var, config)
await cg.register_component(var, config)
await text_sensor.register_text_sensor(var, config)
parent_var = yield cg.get_variable(config[CONF_OUTPUT_ID])
parent_var = await cg.get_variable(config[CONF_LIGHT_HAL_ID])
cg.add(var.set_parent(parent_var)) cg.add(var.set_parent(parent_var))

+ 3
- 2
components/xiaomi_bslamp2/text_sensor/light_mode_text_sensor.h View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "esphome/components/text_sensor/text_sensor.h" #include "esphome/components/text_sensor/text_sensor.h"
#include "../light_hal.h"
namespace esphome { namespace esphome {
namespace xiaomi { namespace xiaomi {
@ -14,7 +15,7 @@ namespace bslamp2 {
*/ */
class XiaomiBslamp2LightModeTextSensor : public text_sensor::TextSensor, public Component { class XiaomiBslamp2LightModeTextSensor : public text_sensor::TextSensor, public Component {
public: public:
void set_parent(XiaomiBslamp2LightOutput *light) { light_ = light; }
void set_parent(LightHAL *light) { light_ = light; }
void setup() { void setup() {
light_->add_on_light_mode_callback([this](std::string light_mode) { light_->add_on_light_mode_callback([this](std::string light_mode) {
@ -26,7 +27,7 @@ class XiaomiBslamp2LightModeTextSensor : public text_sensor::TextSensor, public
} }
protected: protected:
XiaomiBslamp2LightOutput *light_;
LightHAL *light_;
std::string last_light_mode_ = LIGHT_MODE_UNKNOWN; std::string last_light_mode_ = LIGHT_MODE_UNKNOWN;
}; };


Loading…
Cancel
Save