diff --git a/components/xiaomi_bslamp2/__init__.py b/components/xiaomi_bslamp2/__init__.py index fcf4877..5cf0a44 100644 --- a/components/xiaomi_bslamp2/__init__.py +++ b/components/xiaomi_bslamp2/__init__.py @@ -4,7 +4,6 @@ from esphome import pins from esphome.components.ledc.output import LEDCOutput from esphome.components.gpio.output import GPIOBinaryOutput from esphome.components.i2c import I2CComponent, I2CDevice -from esphome.core import coroutine from esphome.core import CORE from esphome.const import ( CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, CONF_TRIGGER_PIN, diff --git a/components/xiaomi_bslamp2/binary_sensor/__init__.py b/components/xiaomi_bslamp2/binary_sensor/__init__.py index 839f13a..eda0afa 100644 --- a/components/xiaomi_bslamp2/binary_sensor/__init__.py +++ b/components/xiaomi_bslamp2/binary_sensor/__init__.py @@ -54,11 +54,11 @@ CONFIG_SCHEMA = cv.All( validate_binary_sensor, ) -def to_code(config): +async def to_code(config): 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_for(config[CONF_FOR])) diff --git a/components/xiaomi_bslamp2/light/__init__.py b/components/xiaomi_bslamp2/light/__init__.py index d57e6d6..5d0c9bb 100644 --- a/components/xiaomi_bslamp2/light/__init__.py +++ b/components/xiaomi_bslamp2/light/__init__.py @@ -2,11 +2,12 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import light from esphome import automation -from esphome.core import coroutine, Lambda +from esphome.core import Lambda from esphome.const import ( CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, CONF_COLOR_TEMPERATURE, 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 @@ -27,11 +28,13 @@ MIRED_MAX = 588 XiaomiBslamp2LightState = bslamp2_ns.class_("XiaomiBslamp2LightState", light.LightState) XiaomiBslamp2LightOutput = bslamp2_ns.class_("XiaomiBslamp2LightOutput", light.LightOutput) +XiaomiBslamp2LightTransition = bslamp2_ns.class_("XiaomiBslamp2LightTransition", light.LightTransition) PresetsContainer = bslamp2_ns.class_("PresetsContainer", cg.Component) Preset = bslamp2_ns.class_("Preset", cg.Component) BrightnessTrigger = bslamp2_ns.class_("BrightnessTrigger", automation.Trigger.template()) ActivatePresetAction = bslamp2_ns.class_("ActivatePresetAction", automation.Action) DiscoAction = bslamp2_ns.class_("DiscoAction", automation.Action) +DiscoAction = bslamp2_ns.class_("DiscoAction", automation.Action) PRESETS_SCHEMA = 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_LIGHT_HAL_ID): cv.use_id(LightHAL), 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.GenerateID(CONF_TRIGGER_ID): cv.declare_id(BrightnessTrigger), @@ -129,49 +135,49 @@ def maybe_simple_preset_action(schema): @automation.register_action( "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) 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_)) if CONF_TRANSITION_LENGTH in config: - template_ = yield cg.templatable( + template_ = await cg.templatable( config[CONF_TRANSITION_LENGTH], args, cg.uint32 ) cg.add(var.set_transition_length(template_)) 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_)) 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_)) 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_)) 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_)) 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_)) 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_)) 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_)) - yield var + return var @automation.register_action( "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) cg.add(var.set_disco_state(False)) - yield var + return var USED_PRESETS = [] @@ -202,40 +208,54 @@ def register_preset_action(value): 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) if CONF_NEXT in config: cg.add(action_var.set_operation(f"next_{config[CONF_NEXT]}")) elif CONF_PRESET in config: 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_)) - 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_)) else: 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_)) - 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]) - 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)) -@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, []): - 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( config[CONF_PRESET_ID], light_var, preset_group, preset_name) 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])) else: 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]) - 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_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)) -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): valid_presets = config.get(CONF_PRESETS, {}); diff --git a/components/xiaomi_bslamp2/light/automation.h b/components/xiaomi_bslamp2/light/automation.h index 8aedfec..e1c7832 100644 --- a/components/xiaomi_bslamp2/light/automation.h +++ b/components/xiaomi_bslamp2/light/automation.h @@ -3,6 +3,7 @@ #include "esphome/core/automation.h" #include "esphome/core/component.h" #include "interfaces.h" +#include "../light_hal.h" #include "light_output.h" #include "light_state.h" #include "presets.h" @@ -14,7 +15,7 @@ namespace bslamp2 { class BrightnessTrigger : public Trigger { public: - explicit BrightnessTrigger(XiaomiBslamp2LightOutput *parent) { + explicit BrightnessTrigger(LightHAL *parent) { parent->add_on_state_callback([this](light::LightColorValues values) { auto new_brightness = values.get_brightness(); if (values.get_state() == 0) diff --git a/components/xiaomi_bslamp2/light/light_output.h b/components/xiaomi_bslamp2/light/light_output.h index 7d717e3..57c8591 100644 --- a/components/xiaomi_bslamp2/light/light_output.h +++ b/components/xiaomi_bslamp2/light/light_output.h @@ -3,7 +3,7 @@ #include "../common.h" #include "../light_hal.h" #include "color_handler_chain.h" -#include "light_transformer.h" +#include "light_transition.h" #include "esphome/core/component.h" #include "esphome/components/ledc/ledc_output.h" @@ -35,19 +35,6 @@ class XiaomiBslamp2LightOutput : public Component, public light::LightOutput { return traits; } - std::unique_ptr create_default_transition() override { - return make_unique( - light_, light_mode_callback_, state_callback_); - } - - void add_on_light_mode_callback(std::function &&callback) { - light_mode_callback_.add(std::move(callback)); - } - - void add_on_state_callback(std::function &&callback) { - state_callback_.add(std::move(callback)); - } - /** * 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; 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 // circuitry master switch after setting the individual channels, @@ -76,8 +63,6 @@ class XiaomiBslamp2LightOutput : public Component, public light::LightOutput { protected: LightHAL *light_; ColorHandler *color_handler_chain = new ColorHandlerChain(); - CallbackManager light_mode_callback_{}; - CallbackManager state_callback_{}; }; } // namespace bslamp2 diff --git a/components/xiaomi_bslamp2/light/light_transformer.h b/components/xiaomi_bslamp2/light/light_transition.h similarity index 75% rename from components/xiaomi_bslamp2/light/light_transformer.h rename to components/xiaomi_bslamp2/light/light_transition.h index f78dba4..62c788a 100644 --- a/components/xiaomi_bslamp2/light/light_transformer.h +++ b/components/xiaomi_bslamp2/light/light_transition.h @@ -3,7 +3,8 @@ #include "../common.h" #include "../light_hal.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" namespace esphome { @@ -11,19 +12,20 @@ namespace xiaomi { 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: - explicit XiaomiBslamp2LightTransitionTransformer( - LightHAL *light, - CallbackManager light_mode_callback, - CallbackManager 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 { + // TODO deprecate or compile for 2018.8.* only. + bool is_finished() { + return is_completed(); + } + + bool is_completed() override { return force_finish_ || get_progress_() >= 1.0f; } @@ -47,9 +49,9 @@ class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTra // 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_); + // 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 apply() override { @@ -62,7 +64,7 @@ class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTra } // Otherwise perform a standard transformation. else { - auto smoothed = light::LightTransitionTransformer::smoothed_progress(get_progress_()); + auto smoothed = smoothed_progress_(get_progress_()); light_->set_rgbw( esphome::lerp(smoothed, start_->red, end_->red), esphome::lerp(smoothed, start_->green, end_->green), @@ -90,8 +92,11 @@ class XiaomiBslamp2LightTransitionTransformer : public light::LightTransitionTra bool force_finish_{false}; GPIOOutputValues *start_ = new GPIOOutputValues(); ColorHandler *end_ = new ColorHandlerChain(); - CallbackManager light_mode_callback_{}; - CallbackManager state_callback_{}; + + protected: + static float smoothed_progress_(float x) { + return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f); + } }; } // namespace bslamp2 diff --git a/components/xiaomi_bslamp2/light_hal.h b/components/xiaomi_bslamp2/light_hal.h index ee0ac91..613c06e 100644 --- a/components/xiaomi_bslamp2/light_hal.h +++ b/components/xiaomi_bslamp2/light_hal.h @@ -45,6 +45,14 @@ class LightHAL : Component, public GPIOOutputValues { void set_master1_pin(gpio::GPIOBinaryOutput *pin) { master1_pin_ = pin; } void set_master2_pin(gpio::GPIOBinaryOutput *pin) { master2_pin_ = pin; } + void add_on_light_mode_callback(std::function &&callback) { + light_mode_callback_.add(std::move(callback)); + } + + void add_on_state_callback(std::function &&callback) { + state_callback_.add(std::move(callback)); + } + /** * Turn on the master switch for the LEDs. */ @@ -94,6 +102,14 @@ class LightHAL : Component, public GPIOOutputValues { 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: bool is_on_{false}; ledc::LEDCOutput *red_pin_; @@ -102,6 +118,8 @@ class LightHAL : Component, public GPIOOutputValues { ledc::LEDCOutput *white_pin_; gpio::GPIOBinaryOutput *master1_pin_; gpio::GPIOBinaryOutput *master2_pin_; + CallbackManager light_mode_callback_{}; + CallbackManager state_callback_{}; }; } // namespace bslamp2 diff --git a/components/xiaomi_bslamp2/output/__init__.py b/components/xiaomi_bslamp2/output/__init__.py index 0e13e9e..ed13219 100644 --- a/components/xiaomi_bslamp2/output/__init__.py +++ b/components/xiaomi_bslamp2/output/__init__.py @@ -24,12 +24,12 @@ CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend( } ).extend(cv.COMPONENT_SCHEMA) -def to_code(config): +async def to_code(config): 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)) def maybe_simple_level_value(schema): diff --git a/components/xiaomi_bslamp2/sensor/__init__.py b/components/xiaomi_bslamp2/sensor/__init__.py index 039ae65..59151dd 100644 --- a/components/xiaomi_bslamp2/sensor/__init__.py +++ b/components/xiaomi_bslamp2/sensor/__init__.py @@ -22,12 +22,12 @@ CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend( } ).extend(cv.COMPONENT_SCHEMA) -def to_code(config): +async def to_code(config): 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_range_from(config[CONF_RANGE_FROM])) cg.add(var.set_range_to(config[CONF_RANGE_TO])) diff --git a/components/xiaomi_bslamp2/text_sensor/__init__.py b/components/xiaomi_bslamp2/text_sensor/__init__.py index ab8d921..27f6c9d 100644 --- a/components/xiaomi_bslamp2/text_sensor/__init__.py +++ b/components/xiaomi_bslamp2/text_sensor/__init__.py @@ -1,9 +1,9 @@ import esphome.codegen as cg import esphome.config_validation as cv 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"] @@ -16,15 +16,15 @@ XiaomiBslamp2LightModeTextSensor = bslamp2_ns.class_( CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend( { 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) -def to_code(config): +async def to_code(config): 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)) diff --git a/components/xiaomi_bslamp2/text_sensor/light_mode_text_sensor.h b/components/xiaomi_bslamp2/text_sensor/light_mode_text_sensor.h index 45e9de5..c3dfb70 100644 --- a/components/xiaomi_bslamp2/text_sensor/light_mode_text_sensor.h +++ b/components/xiaomi_bslamp2/text_sensor/light_mode_text_sensor.h @@ -1,6 +1,7 @@ #pragma once #include "esphome/components/text_sensor/text_sensor.h" +#include "../light_hal.h" namespace esphome { namespace xiaomi { @@ -14,7 +15,7 @@ namespace bslamp2 { */ class XiaomiBslamp2LightModeTextSensor : public text_sensor::TextSensor, public Component { public: - void set_parent(XiaomiBslamp2LightOutput *light) { light_ = light; } + void set_parent(LightHAL *light) { light_ = light; } void setup() { light_->add_on_light_mode_callback([this](std::string light_mode) { @@ -26,7 +27,7 @@ class XiaomiBslamp2LightModeTextSensor : public text_sensor::TextSensor, public } protected: - XiaomiBslamp2LightOutput *light_; + LightHAL *light_; std::string last_light_mode_ = LIGHT_MODE_UNKNOWN; };