diff --git a/esphome/components/cover/__init__.py b/esphome/components/cover/__init__.py index 4d595f11d1..a2590564b9 100644 --- a/esphome/components/cover/__init__.py +++ b/esphome/components/cover/__init__.py @@ -24,15 +24,22 @@ cover_ns = esphome_ns.namespace('cover') Cover = cover_ns.class_('Cover', Nameable) MQTTCoverComponent = cover_ns.class_('MQTTCoverComponent', mqtt.MQTTComponent) -CoverState = cover_ns.class_('CoverState') COVER_OPEN = cover_ns.COVER_OPEN COVER_CLOSED = cover_ns.COVER_CLOSED -validate_cover_state = cv.one_of('OPEN', 'CLOSED', upper=True) COVER_STATES = { 'OPEN': COVER_OPEN, 'CLOSED': COVER_CLOSED, } +validate_cover_state = cv.one_of(*COVER_STATES, upper=True) + +CoverOperation = cover_ns.enum('CoverOperation') +COVER_OPERATIONS = { + 'IDLE': CoverOperation.COVER_OPERATION_IDLE, + 'OPENING': CoverOperation.COVER_OPERATION_OPENING, + 'CLOSING': CoverOperation.COVER_OPERATION_CLOSING, +} +validate_cover_operation = cv.one_of(*COVER_OPERATIONS, upper=True) # Actions OpenAction = cover_ns.class_('OpenAction', Action) @@ -82,8 +89,8 @@ COVER_OPEN_ACTION_SCHEMA = maybe_simple_id({ def cover_open_to_code(config, action_id, template_arg, args): for var in get_variable(config[CONF_ID]): yield None - rhs = var.make_open_action(template_arg) type = OpenAction.template(template_arg) + rhs = type.new(var) yield Pvariable(action_id, rhs, type=type) @@ -97,8 +104,8 @@ COVER_CLOSE_ACTION_SCHEMA = maybe_simple_id({ def cover_close_to_code(config, action_id, template_arg, args): for var in get_variable(config[CONF_ID]): yield None - rhs = var.make_close_action(template_arg) type = CloseAction.template(template_arg) + rhs = type.new(var) yield Pvariable(action_id, rhs, type=type) @@ -112,8 +119,8 @@ COVER_STOP_ACTION_SCHEMA = maybe_simple_id({ def cover_stop_to_code(config, action_id, template_arg, args): for var in get_variable(config[CONF_ID]): yield None - rhs = var.make_stop_action(template_arg) type = StopAction.template(template_arg) + rhs = type.new(var) yield Pvariable(action_id, rhs, type=type) diff --git a/esphome/components/cover/endstop.py b/esphome/components/cover/endstop.py index 982d178a87..a8e8b3e2ae 100644 --- a/esphome/components/cover/endstop.py +++ b/esphome/components/cover/endstop.py @@ -8,9 +8,9 @@ from esphome.const import CONF_CLOSE_ACTION, CONF_CLOSE_DURATION, \ CONF_OPEN_ENDSTOP, CONF_STOP_ACTION, CONF_MAX_DURATION from esphome.cpp_generator import Pvariable, add, get_variable from esphome.cpp_helpers import setup_component -from esphome.cpp_types import App +from esphome.cpp_types import App, Component -EndstopCover = cover.cover_ns.class_('EndstopCover', cover.Cover) +EndstopCover = cover.cover_ns.class_('EndstopCover', cover.Cover, Component) PLATFORM_SCHEMA = cv.nameable(cover.COVER_PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(EndstopCover), diff --git a/esphome/components/cover/template.py b/esphome/components/cover/template.py index 708ee297a9..7d194d7d04 100644 --- a/esphome/components/cover/template.py +++ b/esphome/components/cover/template.py @@ -5,7 +5,8 @@ from esphome.automation import ACTION_REGISTRY from esphome.components import cover import esphome.config_validation as cv from esphome.const import CONF_ASSUMED_STATE, CONF_CLOSE_ACTION, CONF_ID, CONF_LAMBDA, CONF_NAME, \ - CONF_OPEN_ACTION, CONF_OPTIMISTIC, CONF_STATE, CONF_STOP_ACTION + CONF_OPEN_ACTION, CONF_OPTIMISTIC, CONF_STATE, CONF_STOP_ACTION, CONF_POSITION, \ + CONF_CURRENT_OPERATION, CONF_RESTORE_MODE from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable from esphome.cpp_helpers import setup_component from esphome.cpp_types import Action, App, optional @@ -13,6 +14,13 @@ from esphome.cpp_types import Action, App, optional TemplateCover = cover.cover_ns.class_('TemplateCover', cover.Cover) CoverPublishAction = cover.cover_ns.class_('CoverPublishAction', Action) +TemplateCoverRestoreMode = cover.cover_ns.enum('TemplateCoverRestoreMode') +RESTORE_MODES = { + 'NO_RESTORE': TemplateCoverRestoreMode.NO_RESTORE, + 'RESTORE': TemplateCoverRestoreMode.RESTORE, + 'RESTORE_AND_CALL': TemplateCoverRestoreMode.RESTORE_AND_CALL, +} + PLATFORM_SCHEMA = cv.nameable(cover.COVER_PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(TemplateCover), vol.Optional(CONF_LAMBDA): cv.lambda_, @@ -21,19 +29,19 @@ PLATFORM_SCHEMA = cv.nameable(cover.COVER_PLATFORM_SCHEMA.extend({ vol.Optional(CONF_OPEN_ACTION): automation.validate_automation(single=True), vol.Optional(CONF_CLOSE_ACTION): automation.validate_automation(single=True), vol.Optional(CONF_STOP_ACTION): automation.validate_automation(single=True), + vol.Optional(CONF_RESTORE_MODE): cv.one_of(*RESTORE_MODES, upper=True), }).extend(cv.COMPONENT_SCHEMA.schema)) def to_code(config): - rhs = App.make_template_cover(config[CONF_NAME]) + rhs = App.register_component(TemplateCover.new(config[CONF_NAME])) var = Pvariable(config[CONF_ID], rhs) - - cover.setup_cover(var, config) + cover.register_cover(var, config) setup_component(var, config) if CONF_LAMBDA in config: for template_ in process_lambda(config[CONF_LAMBDA], [], - return_type=optional.template(cover.CoverState)): + return_type=optional.template(float)): yield add(var.set_state_lambda(template_)) if CONF_OPEN_ACTION in config: @@ -49,6 +57,8 @@ def to_code(config): add(var.set_optimistic(config[CONF_OPTIMISTIC])) if CONF_ASSUMED_STATE in config: add(var.set_assumed_state(config[CONF_ASSUMED_STATE])) + if CONF_RESTORE_MODE in config: + add(var.set_restore_mode(RESTORE_MODES[config[CONF_RESTORE_MODE]])) BUILD_FLAGS = '-DUSE_TEMPLATE_COVER' @@ -56,7 +66,9 @@ BUILD_FLAGS = '-DUSE_TEMPLATE_COVER' CONF_COVER_TEMPLATE_PUBLISH = 'cover.template.publish' COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({ vol.Required(CONF_ID): cv.use_variable_id(cover.Cover), - vol.Required(CONF_STATE): cv.templatable(cover.validate_cover_state), + vol.Exclusive(CONF_STATE, 'pos'): cv.templatable(cover.validate_cover_state), + vol.Exclusive(CONF_POSITION, 'pos'): cv.templatable(cv.zero_to_one_float), + vol.Optional(CONF_CURRENT_OPERATION): cv.templatable(cover.validate_cover_operation), }) @@ -65,11 +77,22 @@ COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({ def cover_template_publish_to_code(config, action_id, template_arg, args): for var in get_variable(config[CONF_ID]): yield None - rhs = var.make_cover_publish_action(template_arg) type = CoverPublishAction.template(template_arg) + rhs = type.new(var) action = Pvariable(action_id, rhs, type=type) - for template_ in templatable(config[CONF_STATE], args, cover.CoverState, - to_exp=cover.COVER_STATES): - yield None - add(action.set_state(template_)) + if CONF_STATE in config: + for template_ in templatable(config[CONF_STATE], args, float, + to_exp=cover.COVER_STATES): + yield None + add(action.set_position(template_)) + if CONF_POSITION in config: + for template_ in templatable(config[CONF_POSITION], args, float, + to_exp=cover.COVER_STATES): + yield None + add(action.set_position(template_)) + if CONF_CURRENT_OPERATION in config: + for template_ in templatable(config[CONF_CURRENT_OPERATION], args, cover.CoverOperation, + to_exp=cover.COVER_OPERATIONS): + yield None + add(action.set_current_operation(template_)) yield action diff --git a/esphome/components/cover/time_based.py b/esphome/components/cover/time_based.py new file mode 100644 index 0000000000..80411973f2 --- /dev/null +++ b/esphome/components/cover/time_based.py @@ -0,0 +1,44 @@ +import voluptuous as vol + +from esphome import automation +from esphome.components import cover +import esphome.config_validation as cv +from esphome.const import CONF_CLOSE_ACTION, CONF_CLOSE_DURATION, CONF_ID, CONF_NAME, \ + CONF_OPEN_ACTION, CONF_OPEN_DURATION, CONF_STOP_ACTION +from esphome.cpp_generator import Pvariable, add +from esphome.cpp_helpers import setup_component +from esphome.cpp_types import App, Component + +TimeBasedCover = cover.cover_ns.class_('TimeBasedCover', cover.Cover, Component) + +PLATFORM_SCHEMA = cv.nameable(cover.COVER_PLATFORM_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(TimeBasedCover), + vol.Required(CONF_STOP_ACTION): automation.validate_automation(single=True), + + vol.Required(CONF_OPEN_ACTION): automation.validate_automation(single=True), + vol.Required(CONF_OPEN_DURATION): cv.positive_time_period_milliseconds, + + vol.Required(CONF_CLOSE_ACTION): automation.validate_automation(single=True), + vol.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds, +}).extend(cv.COMPONENT_SCHEMA.schema)) + + +def to_code(config): + rhs = App.register_component(TimeBasedCover.new(config[CONF_NAME])) + var = Pvariable(config[CONF_ID], rhs) + cover.register_cover(var, config) + setup_component(var, config) + + automation.build_automations(var.get_stop_trigger(), [], + config[CONF_STOP_ACTION]) + + add(var.set_open_duration(config[CONF_OPEN_DURATION])) + automation.build_automations(var.get_open_trigger(), [], + config[CONF_OPEN_ACTION]) + + add(var.set_close_duration(config[CONF_CLOSE_DURATION])) + automation.build_automations(var.get_close_trigger(), [], + config[CONF_CLOSE_ACTION]) + + +BUILD_FLAGS = '-DUSE_TIME_BASED_COVER' diff --git a/esphome/components/light/__init__.py b/esphome/components/light/__init__.py index a82ecdceef..77b05f995a 100644 --- a/esphome/components/light/__init__.py +++ b/esphome/components/light/__init__.py @@ -32,8 +32,7 @@ AddressableLightRef = AddressableLight.operator('ref') # Actions ToggleAction = light_ns.class_('ToggleAction', Action) -TurnOffAction = light_ns.class_('TurnOffAction', Action) -TurnOnAction = light_ns.class_('TurnOnAction', Action) +LightControlAction = light_ns.class_('LightControlAction', Action) LightColorValues = light_ns.class_('LightColorValues') @@ -265,6 +264,7 @@ RGB_LIGHT_SCHEMA = BRIGHTNESS_ONLY_LIGHT_SCHEMA.extend({ }) ADDRESSABLE_LIGHT_SCHEMA = RGB_LIGHT_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(AddressableLightState), vol.Optional(CONF_EFFECTS): validate_effects(ADDRESSABLE_EFFECTS), vol.Optional(CONF_COLOR_CORRECT): vol.All([cv.percentage], vol.Length(min=3, max=4)), }) @@ -389,7 +389,7 @@ def build_effect(full_config): raise NotImplementedError("Effect {} not implemented".format(next(config.keys()))) -def setup_light_core_(light_var, config): +def setup_light_core_(light_var, output_var, config): if CONF_INTERNAL in config: add(light_var.set_internal(config[CONF_INTERNAL])) if CONF_DEFAULT_TRANSITION_LENGTH in config: @@ -405,14 +405,14 @@ def setup_light_core_(light_var, config): add(light_var.add_effects(effects)) if CONF_COLOR_CORRECT in config: - add(light_var.set_correction(*config[CONF_COLOR_CORRECT])) + add(output_var.set_correction(*config[CONF_COLOR_CORRECT])) setup_mqtt_component(light_var.Pget_mqtt(), config) -def setup_light(light_obj, config): +def setup_light(light_obj, output_var, config): light_var = Pvariable(config[CONF_ID], light_obj, has_side_effects=False) - CORE.add_job(setup_light_core_, light_var, config) + CORE.add_job(setup_light_core_, light_var, output_var, config) BUILD_FLAGS = '-DUSE_LIGHT' @@ -428,8 +428,8 @@ LIGHT_TOGGLE_ACTION_SCHEMA = maybe_simple_id({ def light_toggle_to_code(config, action_id, template_arg, args): for var in get_variable(config[CONF_ID]): yield None - rhs = var.make_toggle_action(template_arg) type = ToggleAction.template(template_arg) + rhs = type.new(var) action = Pvariable(action_id, rhs, type=type) if CONF_TRANSITION_LENGTH in config: for template_ in templatable(config[CONF_TRANSITION_LENGTH], args, uint32): @@ -449,8 +449,8 @@ LIGHT_TURN_OFF_ACTION_SCHEMA = maybe_simple_id({ def light_turn_off_to_code(config, action_id, template_arg, args): for var in get_variable(config[CONF_ID]): yield None - rhs = var.make_turn_off_action(template_arg) - type = TurnOffAction.template(template_arg) + type = LightControlAction.template(template_arg) + rhs = type.new(var) action = Pvariable(action_id, rhs, type=type) if CONF_TRANSITION_LENGTH in config: for template_ in templatable(config[CONF_TRANSITION_LENGTH], args, uint32): @@ -459,30 +459,47 @@ def light_turn_off_to_code(config, action_id, template_arg, args): yield action -CONF_LIGHT_TURN_ON = 'light.turn_on' -LIGHT_TURN_ON_ACTION_SCHEMA = maybe_simple_id({ +CONF_LIGHT_CONTROL = 'light.control' +LIGHT_CONTROL_ACTION_SCHEMA = cv.Schema({ vol.Required(CONF_ID): cv.use_variable_id(LightState), + vol.Optional(CONF_STATE): cv.templatable(cv.boolean), vol.Exclusive(CONF_TRANSITION_LENGTH, 'transformer'): cv.templatable(cv.positive_time_period_milliseconds), vol.Exclusive(CONF_FLASH_LENGTH, 'transformer'): cv.templatable(cv.positive_time_period_milliseconds), + vol.Exclusive(CONF_EFFECT, 'transformer'): cv.templatable(cv.string), vol.Optional(CONF_BRIGHTNESS): cv.templatable(cv.percentage), vol.Optional(CONF_RED): cv.templatable(cv.percentage), vol.Optional(CONF_GREEN): cv.templatable(cv.percentage), vol.Optional(CONF_BLUE): cv.templatable(cv.percentage), vol.Optional(CONF_WHITE): cv.templatable(cv.percentage), - vol.Optional(CONF_COLOR_TEMPERATURE): cv.templatable(cv.positive_float), - vol.Optional(CONF_EFFECT): cv.templatable(cv.string), + vol.Optional(CONF_COLOR_TEMPERATURE): cv.templatable(cv.color_temperature), }) +CONF_LIGHT_TURN_OFF = 'light.turn_off' +LIGHT_TURN_OFF_ACTION_SCHEMA = maybe_simple_id({ + vol.Required(CONF_ID): cv.use_variable_id(LightState), + vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds), + vol.Optional(CONF_STATE, default=False): False, +}) +CONF_LIGHT_TURN_ON = 'light.turn_on' +LIGHT_TURN_ON_ACTION_SCHEMA = maybe_simple_id(LIGHT_CONTROL_ACTION_SCHEMA.extend({ + vol.Optional(CONF_STATE, default=True): True, +})) +@ACTION_REGISTRY.register(CONF_LIGHT_TURN_OFF, LIGHT_TURN_OFF_ACTION_SCHEMA) @ACTION_REGISTRY.register(CONF_LIGHT_TURN_ON, LIGHT_TURN_ON_ACTION_SCHEMA) -def light_turn_on_to_code(config, action_id, template_arg, args): +@ACTION_REGISTRY.register(CONF_LIGHT_CONTROL, LIGHT_CONTROL_ACTION_SCHEMA) +def light_control_to_code(config, action_id, template_arg, args): for var in get_variable(config[CONF_ID]): yield None - rhs = var.make_turn_on_action(template_arg) - type = TurnOnAction.template(template_arg) + type = LightControlAction.template(template_arg) + rhs = type.new(var) action = Pvariable(action_id, rhs, type=type) + if CONF_STATE in config: + for template_ in templatable(config[CONF_STATE], args, bool): + yield None + add(action.set_state(template_)) if CONF_TRANSITION_LENGTH in config: for template_ in templatable(config[CONF_TRANSITION_LENGTH], args, uint32): yield None @@ -492,27 +509,27 @@ def light_turn_on_to_code(config, action_id, template_arg, args): yield None add(action.set_flash_length(template_)) if CONF_BRIGHTNESS in config: - for template_ in templatable(config[CONF_BRIGHTNESS], args, float_): + for template_ in templatable(config[CONF_BRIGHTNESS], args, float): yield None add(action.set_brightness(template_)) if CONF_RED in config: - for template_ in templatable(config[CONF_RED], args, float_): + for template_ in templatable(config[CONF_RED], args, float): yield None add(action.set_red(template_)) if CONF_GREEN in config: - for template_ in templatable(config[CONF_GREEN], args, float_): + for template_ in templatable(config[CONF_GREEN], args, float): yield None add(action.set_green(template_)) if CONF_BLUE in config: - for template_ in templatable(config[CONF_BLUE], args, float_): + for template_ in templatable(config[CONF_BLUE], args, float): yield None add(action.set_blue(template_)) if CONF_WHITE in config: - for template_ in templatable(config[CONF_WHITE], args, float_): + for template_ in templatable(config[CONF_WHITE], args, float): yield None add(action.set_white(template_)) if CONF_COLOR_TEMPERATURE in config: - for template_ in templatable(config[CONF_COLOR_TEMPERATURE], args, float_): + for template_ in templatable(config[CONF_COLOR_TEMPERATURE], args, float): yield None add(action.set_color_temperature(template_)) if CONF_EFFECT in config: diff --git a/esphome/components/light/binary.py b/esphome/components/light/binary.py index a1dc1c20a4..42d42112c9 100644 --- a/esphome/components/light/binary.py +++ b/esphome/components/light/binary.py @@ -2,7 +2,7 @@ import voluptuous as vol from esphome.components import light, output import esphome.config_validation as cv -from esphome.const import CONF_EFFECTS, CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT +from esphome.const import CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT from esphome.cpp_generator import get_variable, variable from esphome.cpp_helpers import setup_component from esphome.cpp_types import App @@ -10,7 +10,7 @@ from esphome.cpp_types import App PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), vol.Required(CONF_OUTPUT): cv.use_variable_id(output.BinaryOutput), -}).extend(light.BINARY_LIGHT_SCHEMA).extend(cv.COMPONENT_SCHEMA.schema)) +}).extend(light.BINARY_LIGHT_SCHEMA.schema).extend(cv.COMPONENT_SCHEMA.schema)) def to_code(config): @@ -18,5 +18,5 @@ def to_code(config): yield rhs = App.make_binary_light(config[CONF_NAME], output_) light_struct = variable(config[CONF_MAKE_ID], rhs) - light.setup_light(light_struct.Pstate, config) + light.setup_light(light_struct.Pstate, light_struct.Poutput, config) setup_component(light_struct.Pstate, config) diff --git a/esphome/components/light/cwww.py b/esphome/components/light/cwww.py index 70ae917182..e8b7dad3e2 100644 --- a/esphome/components/light/cwww.py +++ b/esphome/components/light/cwww.py @@ -1,11 +1,9 @@ import voluptuous as vol from esphome.components import light, output -from esphome.components.light.rgbww import validate_cold_white_colder, \ - validate_color_temperature +from esphome.components.light.rgbww import validate_cold_white_colder import esphome.config_validation as cv -from esphome.const import CONF_COLD_WHITE, CONF_COLD_WHITE_COLOR_TEMPERATURE, \ - CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \ +from esphome.const import CONF_COLD_WHITE, CONF_COLD_WHITE_COLOR_TEMPERATURE, CONF_MAKE_ID, \ CONF_NAME, CONF_WARM_WHITE, CONF_WARM_WHITE_COLOR_TEMPERATURE from esphome.cpp_generator import get_variable, variable from esphome.cpp_helpers import setup_component @@ -15,9 +13,9 @@ PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), vol.Required(CONF_COLD_WHITE): cv.use_variable_id(output.FloatOutput), vol.Required(CONF_WARM_WHITE): cv.use_variable_id(output.FloatOutput), - vol.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): validate_color_temperature, - vol.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): validate_color_temperature, -}).extend(light.BRIGHTNESS_ONLY_LIGHT_SCHEMA).extend(cv.COMPONENT_SCHEMA.schema), + vol.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature, + vol.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature, +}).extend(light.BRIGHTNESS_ONLY_LIGHT_SCHEMA.schema).extend(cv.COMPONENT_SCHEMA.schema), validate_cold_white_colder) @@ -30,5 +28,5 @@ def to_code(config): config[CONF_WARM_WHITE_COLOR_TEMPERATURE], cold_white, warm_white) light_struct = variable(config[CONF_MAKE_ID], rhs) - light.setup_light(light_struct.Pstate, config) + light.setup_light(light_struct.Pstate, light_struct.Poutput, config) setup_component(light_struct.Pstate, config) diff --git a/esphome/components/light/fastled_clockless.py b/esphome/components/light/fastled_clockless.py index 2187a0b6fb..f50498a681 100644 --- a/esphome/components/light/fastled_clockless.py +++ b/esphome/components/light/fastled_clockless.py @@ -4,8 +4,7 @@ from esphome import pins from esphome.components import light from esphome.components.power_supply import PowerSupplyComponent import esphome.config_validation as cv -from esphome.const import CONF_CHIPSET, CONF_COLOR_CORRECT, CONF_DEFAULT_TRANSITION_LENGTH, \ - CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, \ +from esphome.const import CONF_CHIPSET, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, \ CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, CONF_RGB_ORDER from esphome.cpp_generator import RawExpression, TemplateArguments, add, get_variable, variable from esphome.cpp_helpers import setup_component @@ -57,7 +56,6 @@ def validate(value): MakeFastLEDLight = Application.struct('MakeFastLEDLight') PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ - cv.GenerateID(): cv.declare_variable_id(light.AddressableLightState), cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeFastLEDLight), vol.Required(CONF_CHIPSET): cv.one_of(*TYPES, upper=True), @@ -68,7 +66,7 @@ PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_RGB_ORDER): cv.one_of(*RGB_ORDERS, upper=True), vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent), -}).extend(light.RGB_LIGHT_SCHEMA).extend(cv.COMPONENT_SCHEMA.schema), validate) +}).extend(light.ADDRESSABLE_LIGHT_SCHEMA.schema).extend(cv.COMPONENT_SCHEMA.schema), validate) def to_code(config): @@ -91,7 +89,7 @@ def to_code(config): yield add(fast_led.set_power_supply(power_supply)) - light.setup_light(make.Pstate, config) + light.setup_light(make.Pstate, make.Pfast_led, config) setup_component(fast_led, config) diff --git a/esphome/components/light/fastled_spi.py b/esphome/components/light/fastled_spi.py index ae830d2e4d..a10ba97e2c 100644 --- a/esphome/components/light/fastled_spi.py +++ b/esphome/components/light/fastled_spi.py @@ -34,7 +34,6 @@ RGB_ORDERS = [ MakeFastLEDLight = Application.struct('MakeFastLEDLight') PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ - cv.GenerateID(): cv.declare_variable_id(light.AddressableLightState), cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeFastLEDLight), vol.Required(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True), @@ -47,7 +46,7 @@ PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent), vol.Optional(CONF_EFFECTS): light.validate_effects(light.ADDRESSABLE_EFFECTS), -}).extend(light.ADDRESSABLE_LIGHT_SCHEMA).extend(cv.COMPONENT_SCHEMA.schema)) +}).extend(light.ADDRESSABLE_LIGHT_SCHEMA.schema).extend(cv.COMPONENT_SCHEMA.schema)) def to_code(config): @@ -72,7 +71,7 @@ def to_code(config): yield add(fast_led.set_power_supply(power_supply)) - light.setup_light(make.Pstate, config) + light.setup_light(make.Pstate, make.Pfast_led, config) setup_component(fast_led, config) diff --git a/esphome/components/light/monochromatic.py b/esphome/components/light/monochromatic.py index 338be37e22..1db1120cfd 100644 --- a/esphome/components/light/monochromatic.py +++ b/esphome/components/light/monochromatic.py @@ -10,7 +10,7 @@ from esphome.cpp_types import App PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), vol.Required(CONF_OUTPUT): cv.use_variable_id(output.FloatOutput), -}).extend(light.BRIGHTNESS_ONLY_LIGHT_SCHEMA).extend(cv.COMPONENT_SCHEMA.schema)) +}).extend(light.BRIGHTNESS_ONLY_LIGHT_SCHEMA.schema).extend(cv.COMPONENT_SCHEMA.schema)) def to_code(config): @@ -18,5 +18,5 @@ def to_code(config): yield rhs = App.make_monochromatic_light(config[CONF_NAME], output_) light_struct = variable(config[CONF_MAKE_ID], rhs) - light.setup_light(light_struct.Pstate, config) + light.setup_light(light_struct.Pstate, light_struct.Poutput, config) setup_component(light_struct.Pstate, config) diff --git a/esphome/components/light/neopixelbus.py b/esphome/components/light/neopixelbus.py index 9ace51c118..5ba0fd889a 100644 --- a/esphome/components/light/neopixelbus.py +++ b/esphome/components/light/neopixelbus.py @@ -5,9 +5,8 @@ from esphome.components import light from esphome.components.light import AddressableLight from esphome.components.power_supply import PowerSupplyComponent import esphome.config_validation as cv -from esphome.const import CONF_CLOCK_PIN, CONF_COLOR_CORRECT, CONF_DATA_PIN, \ - CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_METHOD, \ - CONF_NAME, CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, CONF_TYPE, CONF_VARIANT +from esphome.const import CONF_CLOCK_PIN, CONF_DATA_PIN, CONF_MAKE_ID, CONF_METHOD, CONF_NAME, \ + CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, CONF_TYPE, CONF_VARIANT from esphome.core import CORE from esphome.cpp_generator import TemplateArguments, add, get_variable, variable from esphome.cpp_helpers import setup_component @@ -131,7 +130,6 @@ def validate(config): MakeNeoPixelBusLight = Application.struct('MakeNeoPixelBusLight') PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ - cv.GenerateID(): cv.declare_variable_id(light.AddressableLightState), cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeNeoPixelBusLight), vol.Optional(CONF_TYPE, default='GRB'): validate_type, @@ -144,7 +142,7 @@ PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ vol.Required(CONF_NUM_LEDS): cv.positive_not_null_int, vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent), -}).extend(light.ADDRESSABLE_LIGHT_SCHEMA).extend(cv.COMPONENT_SCHEMA.schema), +}).extend(light.ADDRESSABLE_LIGHT_SCHEMA.schema).extend(cv.COMPONENT_SCHEMA.schema), validate, validate_method_pin) @@ -175,7 +173,7 @@ def to_code(config): yield add(output.set_power_supply(power_supply)) - light.setup_light(make.Pstate, config) + light.setup_light(make.Pstate, output, config) setup_component(output, config) diff --git a/esphome/components/light/partition.py b/esphome/components/light/partition.py index 30f8d054a0..122f3d2fc6 100644 --- a/esphome/components/light/partition.py +++ b/esphome/components/light/partition.py @@ -3,8 +3,7 @@ import voluptuous as vol from esphome.components import light from esphome.components.light import AddressableLight import esphome.config_validation as cv -from esphome.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_FROM, \ - CONF_GAMMA_CORRECT, CONF_ID, CONF_MAKE_ID, CONF_NAME, CONF_SEGMENTS, CONF_TO +from esphome.const import CONF_FROM, CONF_ID, CONF_MAKE_ID, CONF_NAME, CONF_SEGMENTS, CONF_TO from esphome.cpp_generator import get_variable, variable from esphome.cpp_types import App, Application @@ -29,7 +28,7 @@ PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ vol.Required(CONF_FROM): cv.positive_int, vol.Required(CONF_TO): cv.positive_int, }, validate_from_to), vol.Length(min=1)), -}).extend(light.ADDRESSABLE_LIGHT_SCHEMA)) +}).extend(light.ADDRESSABLE_LIGHT_SCHEMA.schema)) def to_code(config): @@ -42,4 +41,4 @@ def to_code(config): rhs = App.make_partition_light(config[CONF_NAME], segments) make = variable(config[CONF_MAKE_ID], rhs) - light.setup_light(make.Pstate, config) + light.setup_light(make.Pstate, make.Ppartition, config) diff --git a/esphome/components/light/rgb.py b/esphome/components/light/rgb.py index 355469a4bd..14ada47a74 100644 --- a/esphome/components/light/rgb.py +++ b/esphome/components/light/rgb.py @@ -2,8 +2,7 @@ import voluptuous as vol from esphome.components import light, output import esphome.config_validation as cv -from esphome.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, \ - CONF_GAMMA_CORRECT, CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED +from esphome.const import CONF_BLUE, CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED from esphome.cpp_generator import get_variable, variable from esphome.cpp_helpers import setup_component from esphome.cpp_types import App @@ -13,7 +12,7 @@ PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ vol.Required(CONF_RED): cv.use_variable_id(output.FloatOutput), vol.Required(CONF_GREEN): cv.use_variable_id(output.FloatOutput), vol.Required(CONF_BLUE): cv.use_variable_id(output.FloatOutput), -}).extend(light.RGB_LIGHT_SCHEMA).extend(cv.COMPONENT_SCHEMA.schema)) +}).extend(light.RGB_LIGHT_SCHEMA.schema).extend(cv.COMPONENT_SCHEMA.schema)) def to_code(config): @@ -25,5 +24,5 @@ def to_code(config): yield rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue) light_struct = variable(config[CONF_MAKE_ID], rhs) - light.setup_light(light_struct.Pstate, config) + light.setup_light(light_struct.Pstate, light_struct.Poutput, config) setup_component(light_struct.Pstate, config) diff --git a/esphome/components/light/rgbw.py b/esphome/components/light/rgbw.py index 4c035f738a..eed78dc56d 100644 --- a/esphome/components/light/rgbw.py +++ b/esphome/components/light/rgbw.py @@ -13,7 +13,7 @@ PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ vol.Required(CONF_GREEN): cv.use_variable_id(output.FloatOutput), vol.Required(CONF_BLUE): cv.use_variable_id(output.FloatOutput), vol.Required(CONF_WHITE): cv.use_variable_id(output.FloatOutput), -}).extend(light.RGB_LIGHT_SCHEMA).extend(cv.COMPONENT_SCHEMA.schema)) +}).extend(light.RGB_LIGHT_SCHEMA.schema).extend(cv.COMPONENT_SCHEMA.schema)) def to_code(config): @@ -27,5 +27,5 @@ def to_code(config): yield rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white) light_struct = variable(config[CONF_MAKE_ID], rhs) - light.setup_light(light_struct.Pstate, config) + light.setup_light(light_struct.Pstate, light_struct.Poutput, config) setup_component(light_struct.Pstate, config) diff --git a/esphome/components/light/rgbww.py b/esphome/components/light/rgbww.py index 71c786b396..0a4691f156 100644 --- a/esphome/components/light/rgbww.py +++ b/esphome/components/light/rgbww.py @@ -3,23 +3,13 @@ import voluptuous as vol from esphome.components import light, output import esphome.config_validation as cv from esphome.const import CONF_BLUE, CONF_COLD_WHITE, CONF_COLD_WHITE_COLOR_TEMPERATURE, \ - CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_GREEN, CONF_MAKE_ID, \ - CONF_NAME, CONF_RED, CONF_WARM_WHITE, CONF_WARM_WHITE_COLOR_TEMPERATURE + CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_WARM_WHITE, \ + CONF_WARM_WHITE_COLOR_TEMPERATURE from esphome.cpp_generator import get_variable, variable from esphome.cpp_helpers import setup_component from esphome.cpp_types import App -def validate_color_temperature(value): - try: - val = cv.float_with_unit('Color Temperature', 'mireds')(value) - except vol.Invalid: - val = 1000000.0 / cv.float_with_unit('Color Temperature', 'K')(value) - if val < 0: - raise vol.Invalid("Color temperature cannot be negative") - return val - - def validate_cold_white_colder(value): cw = value[CONF_COLD_WHITE_COLOR_TEMPERATURE] ww = value[CONF_WARM_WHITE_COLOR_TEMPERATURE] @@ -37,9 +27,10 @@ PLATFORM_SCHEMA = cv.nameable(light.PLATFORM_SCHEMA.extend({ vol.Required(CONF_BLUE): cv.use_variable_id(output.FloatOutput), vol.Required(CONF_COLD_WHITE): cv.use_variable_id(output.FloatOutput), vol.Required(CONF_WARM_WHITE): cv.use_variable_id(output.FloatOutput), - vol.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): validate_color_temperature, - vol.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): validate_color_temperature, -}).extend(light.RGB_LIGHT_SCHEMA).extend(cv.COMPONENT_SCHEMA.schema), validate_cold_white_colder) + vol.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature, + vol.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature, +}).extend(light.RGB_LIGHT_SCHEMA.schema).extend(cv.COMPONENT_SCHEMA.schema), + validate_cold_white_colder) def to_code(config): @@ -57,5 +48,5 @@ def to_code(config): config[CONF_WARM_WHITE_COLOR_TEMPERATURE], red, green, blue, cold_white, warm_white) light_struct = variable(config[CONF_MAKE_ID], rhs) - light.setup_light(light_struct.Pstate, config) + light.setup_light(light_struct.Pstate, light_struct.Poutput, config) setup_component(light_struct.Pstate, config) diff --git a/esphome/config_validation.py b/esphome/config_validation.py index c9d5bb01d5..10a5111e25 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -483,6 +483,20 @@ def temperature(value): raise orig_err +_color_temperature_mireds = float_with_unit('Color Temperature', ur'(mireds|Mireds)') +_color_temperature_kelvin = float_with_unit('Color Temperature', ur'(K|Kelvin)') + + +def color_temperature(value): + try: + val = _color_temperature_mireds(value) + except vol.Invalid: + val = 1000000.0 / _color_temperature_kelvin(value) + if val < 0: + raise vol.Invalid("Color temperature cannot be negative") + return val + + def validate_bytes(value): value = string(value) match = re.match(r"^([0-9]+)\s*(\w*?)(?:byte|B|b)?s?$", value) diff --git a/esphome/const.py b/esphome/const.py index 8b4c44a55a..4ef60dfca8 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -308,6 +308,7 @@ CONF_CLOSE_ENDSTOP = 'close_endstop' CONF_CLOSE_DURATION = 'close_duration' CONF_MAX_DURATION = 'max_duration' CONF_RC_SWITCH_RAW = 'rc_switch_raw' +CONF_CURRENT_OPERATION = 'current_operation' CONF_RC_SWITCH_TYPE_A = 'rc_switch_type_a' CONF_RC_SWITCH_TYPE_B = 'rc_switch_type_b' CONF_RC_SWITCH_TYPE_C = 'rc_switch_type_c' diff --git a/esphome/cpp_generator.py b/esphome/cpp_generator.py index 11a1cf0811..0d59dd8db0 100644 --- a/esphome/cpp_generator.py +++ b/esphome/cpp_generator.py @@ -190,9 +190,9 @@ class LambdaExpression(Expression): self.parameters = parameters self.requires.append(self.parameters) self.capture = capture - self.return_type = safe_exp(return_type) + self.return_type = safe_exp(return_type) if return_type is not None else None if return_type is not None: - self.requires.append(return_type) + self.requires.append(self.return_type) for i in range(1, len(parts), 3): self.requires.append(parts[i]) diff --git a/tests/test1.yaml b/tests/test1.yaml index ff75ac29eb..56da4e708f 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -88,11 +88,11 @@ mqtt: ESP_LOGD("main", "The data is: %d", data); - light.turn_on: id: living_room_lights - transition_length: !lambda |- - int length = 1000; - if (x.containsKey("length")) - length = x["length"]; - return length; + brightness: !lambda |- + float brightness = 1.0; + if (x.containsKey("brightness")) + brightness = x["brightness"]; + return brightness; effect: !lambda |- const char *effect = "None"; if (x.containsKey("effect"))