From 6e85a741ae176647d416878d77a9e51206d4761f Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Sat, 2 Jun 2018 22:22:20 +0200 Subject: [PATCH] New coroutine-based task execution --- esphomeyaml/__main__.py | 65 ++-- esphomeyaml/automation.py | 308 ++++++++++++------ esphomeyaml/components/ads1115.py | 4 +- .../components/binary_sensor/__init__.py | 50 +-- .../components/binary_sensor/esp32_ble.py | 10 +- .../components/binary_sensor/esp32_touch.py | 10 +- esphomeyaml/components/binary_sensor/gpio.py | 17 +- .../components/binary_sensor/status.py | 13 +- .../components/binary_sensor/template.py | 15 +- esphomeyaml/components/cover/__init__.py | 15 +- esphomeyaml/components/cover/template.py | 24 +- esphomeyaml/components/dallas.py | 4 +- esphomeyaml/components/deep_sleep.py | 12 +- esphomeyaml/components/esp32_ble.py | 8 +- esphomeyaml/components/esp32_touch.py | 3 +- esphomeyaml/components/fan/__init__.py | 18 +- esphomeyaml/components/fan/binary.py | 17 +- esphomeyaml/components/fan/speed.py | 16 +- esphomeyaml/components/i2c.py | 8 +- esphomeyaml/components/ir_transmitter.py | 12 +- esphomeyaml/components/light/__init__.py | 15 +- esphomeyaml/components/light/binary.py | 10 +- .../components/light/fastled_clockless.py | 15 +- esphomeyaml/components/light/fastled_spi.py | 15 +- esphomeyaml/components/light/monochromatic.py | 10 +- esphomeyaml/components/light/rgb.py | 22 +- esphomeyaml/components/light/rgbw.py | 28 +- esphomeyaml/components/logger.py | 10 +- esphomeyaml/components/mqtt.py | 17 +- esphomeyaml/components/ota.py | 8 +- esphomeyaml/components/output/__init__.py | 9 +- esphomeyaml/components/output/esp8266_pwm.py | 14 +- esphomeyaml/components/output/gpio.py | 12 +- esphomeyaml/components/output/ledc.py | 8 +- esphomeyaml/components/output/pca9685.py | 16 +- esphomeyaml/components/pca9685.py | 4 +- esphomeyaml/components/pcf8574.py | 10 +- esphomeyaml/components/power_supply.py | 14 +- esphomeyaml/components/sensor/__init__.py | 149 +++++---- esphomeyaml/components/sensor/adc.py | 11 +- esphomeyaml/components/sensor/ads1115.py | 10 +- esphomeyaml/components/sensor/bh1750.py | 11 +- esphomeyaml/components/sensor/bme280.py | 23 +- esphomeyaml/components/sensor/bme680.py | 28 +- esphomeyaml/components/sensor/bmp085.py | 18 +- esphomeyaml/components/sensor/dallas.py | 9 +- esphomeyaml/components/sensor/dht.py | 22 +- esphomeyaml/components/sensor/dht12.py | 18 +- esphomeyaml/components/sensor/hdc1080.py | 19 +- esphomeyaml/components/sensor/htu21d.py | 18 +- esphomeyaml/components/sensor/max6675.py | 23 +- esphomeyaml/components/sensor/mpu6050.py | 45 ++- .../components/sensor/pulse_counter.py | 11 +- .../components/sensor/rotary_encoder.py | 23 +- esphomeyaml/components/sensor/sht3xd.py | 18 +- esphomeyaml/components/sensor/template.py | 15 +- esphomeyaml/components/sensor/tsl2561.py | 11 +- esphomeyaml/components/sensor/ultrasonic.py | 19 +- esphomeyaml/components/switch/__init__.py | 24 +- esphomeyaml/components/switch/gpio.py | 13 +- .../components/switch/ir_transmitter.py | 7 +- esphomeyaml/components/switch/output.py | 16 +- esphomeyaml/components/switch/restart.py | 8 +- esphomeyaml/components/switch/shutdown.py | 8 +- esphomeyaml/components/switch/template.py | 20 +- esphomeyaml/components/web_server.py | 8 +- esphomeyaml/components/wifi.py | 14 +- esphomeyaml/config.py | 62 +++- esphomeyaml/config_validation.py | 52 +-- esphomeyaml/const.py | 2 + esphomeyaml/core.py | 49 +++ esphomeyaml/dashboard/dashboard.py | 18 +- esphomeyaml/helpers.py | 145 ++++++--- esphomeyaml/pins.py | 3 +- esphomeyaml/yaml_util.py | 6 + pylintrc | 1 + 76 files changed, 1145 insertions(+), 678 deletions(-) diff --git a/esphomeyaml/__main__.py b/esphomeyaml/__main__.py index 42bf3680c..b044622eb 100644 --- a/esphomeyaml/__main__.py +++ b/esphomeyaml/__main__.py @@ -1,11 +1,11 @@ from __future__ import print_function import argparse -from datetime import datetime import logging import os import random import sys +from datetime import datetime from esphomeyaml import const, core, mqtt, wizard, writer, yaml_util from esphomeyaml.config import core_to_code, get_component, iter_components, read_config @@ -13,7 +13,7 @@ from esphomeyaml.const import CONF_BAUD_RATE, CONF_DOMAIN, CONF_ESPHOMEYAML, CON CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI, ESP_PLATFORM_ESP8266 from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, _EXPRESSIONS, add, \ - add_task, color, get_variable, indent, quote, statement + add_task, color, flush_tasks, indent, quote, statement _LOGGER = logging.getLogger(__name__) @@ -113,26 +113,21 @@ def run_miniterm(config, port, escape=False): def write_cpp(config): _LOGGER.info("Generating C++ source...") - add_task(core_to_code, config[CONF_ESPHOMEYAML]) + add_task(core_to_code, config[CONF_ESPHOMEYAML], 'esphomeyaml') for domain in PRE_INITIALIZE: if domain == CONF_ESPHOMEYAML: continue if domain in config: - add_task(get_component(domain).to_code, config[domain]) - - # Clear queue - get_variable(None) - add(RawStatement('')) + add_task(get_component(domain).to_code, config[domain], domain) for domain, component, conf in iter_components(config): if domain in PRE_INITIALIZE: continue if not hasattr(component, 'to_code'): continue - add_task(component.to_code, conf) + add_task(component.to_code, conf, domain) - # Clear queue - get_variable(None) + flush_tasks() add(RawStatement('')) add(RawStatement('')) @@ -157,9 +152,12 @@ def write_cpp(config): return 0 -def compile_program(config): +def compile_program(args, config): _LOGGER.info("Compiling app...") - return run_platformio('platformio', 'run', '-d', get_base_path(config)) + command = ['platformio', 'run', '-d', get_base_path(config)] + if args.verbose: + command.append('-v') + return run_platformio(*command) def get_upload_host(config): @@ -188,8 +186,11 @@ def upload_program(config, args, port): if port != 'OTA': if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266 and args.use_esptoolpy: return upload_using_esptool(config, port) - return run_platformio('platformio', 'run', '-d', get_base_path(config), - '-t', 'upload', '--upload-port', port) + command = ['platformio', 'run', '-d', get_base_path(config), + '-t', 'upload', '--upload-port', port] + if args.verbose: + command.append('-v') + return run_platformio(*command) if 'ota' not in config: _LOGGER.error("No serial port found and OTA not enabled. Can't upload!") @@ -223,8 +224,9 @@ def clean_mqtt(config, args): return mqtt.clear_topic(config, args.topic, args.username, args.password, args.client_id) -def setup_log(): - logging.basicConfig(level=logging.INFO) +def setup_log(debug=False): + log_level = logging.DEBUG if debug else logging.INFO + logging.basicConfig(level=log_level) fmt = "%(levelname)s [%(name)s] %(message)s" colorfmt = "%(log_color)s{}%(reset)s".format(fmt) datefmt = '%H:%M:%S' @@ -253,7 +255,28 @@ def command_wizard(args): return wizard.wizard(args.configuration) +def strip_default_ids(config): + value = config + if isinstance(config, list): + value = type(config)() + for x in config: + if isinstance(x, core.ID) and not x.is_manual: + continue + value.append(strip_default_ids(x)) + return value + elif isinstance(config, dict): + value = type(config)() + for k, v in config.iteritems(): + if isinstance(v, core.ID) and not v.is_manual: + continue + value[k] = strip_default_ids(v) + return value + return value + + def command_config(args, config): + if not args.verbose: + config = strip_default_ids(config) print(yaml_util.dump(config)) return 0 @@ -262,7 +285,7 @@ def command_compile(args, config): exit_code = write_cpp(config) if exit_code != 0: return exit_code - exit_code = compile_program(config) + exit_code = compile_program(args, config) if exit_code != 0: return exit_code _LOGGER.info(u"Successfully compiled program.") @@ -287,7 +310,7 @@ def command_run(args, config): exit_code = write_cpp(config) if exit_code != 0: return exit_code - exit_code = compile_program(config) + exit_code = compile_program(args, config) if exit_code != 0: return exit_code _LOGGER.info(u"Successfully compiled program.") @@ -339,6 +362,8 @@ POST_CONFIG_ACTIONS = { def parse_args(argv): parser = argparse.ArgumentParser(prog='esphomeyaml') + parser.add_argument('-v', '--verbose', help="Enable verbose esphomeyaml logs.", + action='store_true') parser.add_argument('configuration', help='Your YAML configuration file.') subparsers = parser.add_subparsers(help='Commands', dest='command') @@ -407,8 +432,8 @@ def parse_args(argv): def run_esphomeyaml(argv): - setup_log() args = parse_args(argv) + setup_log(args.verbose) if args.command in PRE_CONFIG_ACTIONS: try: return PRE_CONFIG_ACTIONS[args.command](args) diff --git a/esphomeyaml/automation.py b/esphomeyaml/automation.py index c7de26217..f42c0a122 100644 --- a/esphomeyaml/automation.py +++ b/esphomeyaml/automation.py @@ -2,11 +2,12 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml.components import cover, fan -from esphomeyaml.const import CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, CONF_BLUE, \ - CONF_BRIGHTNESS, CONF_CONDITION_ID, CONF_DELAY, CONF_EFFECT, CONF_FLASH_LENGTH, CONF_GREEN, \ - CONF_ID, CONF_IF, CONF_LAMBDA, CONF_OR, CONF_OSCILLATING, CONF_PAYLOAD, \ - CONF_QOS, CONF_RANGE, CONF_RED, CONF_RETAIN, CONF_SPEED, CONF_THEN, CONF_TOPIC, \ - CONF_TRANSITION_LENGTH, CONF_TRIGGER_ID, CONF_WHITE, CONF_ABOVE, CONF_BELOW +from esphomeyaml.const import CONF_ABOVE, CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, \ + CONF_BELOW, \ + CONF_BLUE, CONF_BRIGHTNESS, CONF_CONDITION_ID, CONF_DELAY, CONF_EFFECT, CONF_FLASH_LENGTH, \ + CONF_GREEN, CONF_ID, CONF_IF, CONF_LAMBDA, CONF_OR, CONF_OSCILLATING, CONF_PAYLOAD, CONF_QOS, \ + CONF_RANGE, CONF_RED, CONF_RETAIN, CONF_SPEED, CONF_THEN, CONF_TOPIC, CONF_TRANSITION_LENGTH, \ + CONF_TRIGGER_ID, CONF_WHITE from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, TemplateArguments, add, \ bool_, esphomelib_ns, float_, get_variable, process_lambda, std_string, templatable, uint32, \ @@ -32,7 +33,7 @@ ACTION_KEYS = [CONF_DELAY, CONF_MQTT_PUBLISH, CONF_LIGHT_TOGGLE, CONF_LIGHT_TURN CONF_FAN_TURN_OFF, CONF_FAN_TURN_ON] ACTIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({ - cv.GenerateID('action', CONF_ACTION_ID): cv.register_variable_id, + cv.GenerateID(CONF_ACTION_ID): cv.declare_variable_id(None), vol.Optional(CONF_DELAY): cv.templatable(cv.positive_time_period_milliseconds), vol.Optional(CONF_MQTT_PUBLISH): vol.Schema({ vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic), @@ -41,15 +42,15 @@ ACTIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({ vol.Optional(CONF_RETAIN): cv.templatable(cv.boolean), }), vol.Optional(CONF_LIGHT_TOGGLE): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds), }), vol.Optional(CONF_LIGHT_TURN_OFF): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds), }), vol.Optional(CONF_LIGHT_TURN_ON): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), vol.Exclusive(CONF_TRANSITION_LENGTH, 'transformer'): cv.templatable(cv.positive_time_period_milliseconds), vol.Exclusive(CONF_FLASH_LENGTH, 'transformer'): @@ -62,40 +63,40 @@ ACTIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({ vol.Optional(CONF_EFFECT): cv.templatable(cv.string), }), vol.Optional(CONF_SWITCH_TOGGLE): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_SWITCH_TURN_OFF): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_SWITCH_TURN_ON): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_COVER_OPEN): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_COVER_CLOSE): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_COVER_STOP): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_COVER_OPEN): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_COVER_CLOSE): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_COVER_STOP): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_FAN_TOGGLE): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_FAN_TURN_OFF): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), }), vol.Optional(CONF_FAN_TURN_ON): vol.Schema({ - vol.Required(CONF_ID): cv.variable_id, + vol.Required(CONF_ID): cv.use_variable_id(None), vol.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean), vol.Optional(CONF_SPEED): cv.templatable(fan.validate_fan_speed), }), @@ -115,7 +116,7 @@ def validate_recursive_condition(value): CONDITION_KEYS = [CONF_AND, CONF_OR, CONF_RANGE, CONF_LAMBDA] CONDITIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({ - cv.GenerateID('condition', CONF_CONDITION_ID): cv.register_variable_id, + cv.GenerateID(CONF_CONDITION_ID): cv.declare_variable_id(None), vol.Optional(CONF_AND): validate_recursive_condition, vol.Optional(CONF_OR): validate_recursive_condition, vol.Optional(CONF_RANGE): vol.All(vol.Schema({ @@ -132,8 +133,8 @@ RangeCondition = esphomelib_ns.RangeCondition LambdaCondition = esphomelib_ns.LambdaCondition AUTOMATION_SCHEMA = vol.Schema({ - cv.GenerateID('trigger', CONF_TRIGGER_ID): cv.register_variable_id, - cv.GenerateID('automation', CONF_AUTOMATION_ID): cv.register_variable_id, + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(None), + cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(None), vol.Optional(CONF_IF): CONDITIONS_SCHEMA, vol.Required(CONF_THEN): ACTIONS_SCHEMA, }) @@ -142,156 +143,263 @@ AUTOMATION_SCHEMA = vol.Schema({ def build_condition(config, arg_type): template_arg = TemplateArguments(arg_type) if CONF_AND in config: - return AndCondition.new(template_arg, build_conditions(config[CONF_AND], template_arg)) - if CONF_OR in config: - return OrCondition.new(template_arg, build_conditions(config[CONF_OR], template_arg)) - if CONF_LAMBDA in config: - return LambdaCondition.new(template_arg, - process_lambda(config[CONF_LAMBDA], [(arg_type, 'x')])) - if CONF_RANGE in config: + yield AndCondition.new(template_arg, build_conditions(config[CONF_AND], template_arg)) + elif CONF_OR in config: + yield OrCondition.new(template_arg, build_conditions(config[CONF_OR], template_arg)) + elif CONF_LAMBDA in config: + lambda_ = None + for lambda_ in process_lambda(config[CONF_LAMBDA], [(arg_type, 'x')]): + yield + yield LambdaCondition.new(template_arg, lambda_) + elif CONF_RANGE in config: conf = config[CONF_RANGE] rhs = RangeCondition.new(template_arg) - condition = Pvariable(RangeCondition.template(template_arg), config[CONF_CONDITION_ID], rhs) + type = RangeCondition.template(template_arg) + condition = Pvariable(config[CONF_CONDITION_ID], rhs, type=type) if CONF_ABOVE in conf: - condition.set_min(templatable(conf[CONF_ABOVE], arg_type, float_)) + template_ = None + for template_ in templatable(conf[CONF_ABOVE], arg_type, float_): + yield + condition.set_min(template_) if CONF_BELOW in conf: - condition.set_max(templatable(conf[CONF_BELOW], arg_type, float_)) - return condition - raise ESPHomeYAMLError(u"Unsupported condition {}".format(config)) + template_ = None + for template_ in templatable(conf[CONF_BELOW], arg_type, float_): + yield + condition.set_max(template_) + yield condition + else: + raise ESPHomeYAMLError(u"Unsupported condition {}".format(config)) def build_conditions(config, arg_type): - return ArrayInitializer(*[build_condition(x, arg_type) for x in config]) + conditions = [] + for conf in config: + condition = None + for condition in build_condition(conf, arg_type): + yield None + conditions.append(condition) + yield ArrayInitializer(*conditions) def build_action(config, arg_type): from esphomeyaml.components import light, mqtt, switch template_arg = TemplateArguments(arg_type) + # Keep pylint from freaking out + var = None if CONF_DELAY in config: rhs = App.register_component(DelayAction.new(template_arg)) - action = Pvariable(DelayAction.template(template_arg), config[CONF_ACTION_ID], rhs) - add(action.set_delay(templatable(config[CONF_DELAY], arg_type, uint32))) - return action + type = DelayAction.template(template_arg) + action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) + template_ = None + for template_ in templatable(config[CONF_DELAY], arg_type, uint32): + yield + add(action.set_delay(template_)) + yield action elif CONF_LAMBDA in config: - rhs = LambdaAction.new(template_arg, process_lambda(config[CONF_LAMBDA], [(arg_type, 'x')])) - return Pvariable(LambdaAction.template(template_arg), config[CONF_ACTION_ID], rhs) + lambda_ = None + for lambda_ in process_lambda(config[CONF_LAMBDA], [(arg_type, 'x')]): + yield None + rhs = LambdaAction.new(template_arg, lambda_) + type = LambdaAction.template(template_arg) + yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) elif CONF_MQTT_PUBLISH in config: conf = config[CONF_MQTT_PUBLISH] rhs = App.Pget_mqtt_client().Pmake_publish_action() - action = Pvariable(mqtt.MQTTPublishAction.template(template_arg), config[CONF_ACTION_ID], - rhs) - add(action.set_topic(templatable(conf[CONF_TOPIC], arg_type, std_string))) - add(action.set_payload(templatable(conf[CONF_PAYLOAD], arg_type, std_string))) + type = mqtt.MQTTPublishAction.template(template_arg) + action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) + template_ = None + for template_ in templatable(conf[CONF_TOPIC], arg_type, std_string): + yield None + add(action.set_topic(template_)) + + template_ = None + for template_ in templatable(conf[CONF_PAYLOAD], arg_type, std_string): + yield None + add(action.set_payload(template_)) if CONF_QOS in conf: - add(action.set_qos(templatable(conf[CONF_QOS], arg_type, uint8))) + template_ = None + for template_ in templatable(conf[CONF_QOS], arg_type, uint8): + yield + add(action.set_qos(template_)) if CONF_RETAIN in conf: - add(action.set_retain(templatable(conf[CONF_RETAIN], arg_type, bool_))) - return action + template_ = None + for template_ in templatable(conf[CONF_RETAIN], arg_type, bool_): + yield None + add(action.set_retain(template_)) + yield action elif CONF_LIGHT_TOGGLE in config: conf = config[CONF_LIGHT_TOGGLE] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_toggle_action(template_arg) - action = Pvariable(light.ToggleAction.template(template_arg), config[CONF_ACTION_ID], rhs) + type = light.ToggleAction.template(template_arg) + action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) if CONF_TRANSITION_LENGTH in conf: - add(action.set_transition_length( - templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32) - )) - return action + template_ = None + for template_ in templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32): + yield None + add(action.set_transition_length(template_)) + yield action elif CONF_LIGHT_TURN_OFF in config: conf = config[CONF_LIGHT_TURN_OFF] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_turn_off_action(template_arg) - action = Pvariable(light.TurnOffAction.template(template_arg), config[CONF_ACTION_ID], rhs) + type = light.TurnOffAction.template(template_arg) + action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) if CONF_TRANSITION_LENGTH in conf: - add(action.set_transition_length( - templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32) - )) - return action + template_ = None + for template_ in templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32): + yield None + add(action.set_transition_length(template_)) + yield action elif CONF_LIGHT_TURN_ON in config: conf = config[CONF_LIGHT_TURN_ON] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_turn_on_action(template_arg) - action = Pvariable(light.TurnOnAction.template(template_arg), config[CONF_ACTION_ID], rhs) + type = light.TurnOnAction.template(template_arg) + action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) if CONF_TRANSITION_LENGTH in conf: - add(action.set_transition_length( - templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32) - )) + template_ = None + for template_ in templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32): + yield None + add(action.set_transition_length(template_)) if CONF_FLASH_LENGTH in conf: - add(action.set_flash_length(templatable(conf[CONF_FLASH_LENGTH], arg_type, uint32))) + template_ = None + for template_ in templatable(conf[CONF_FLASH_LENGTH], arg_type, uint32): + yield None + add(action.set_flash_length(template_)) if CONF_BRIGHTNESS in conf: - add(action.set_brightness(templatable(conf[CONF_BRIGHTNESS], arg_type, float_))) + template_ = None + for template_ in templatable(conf[CONF_BRIGHTNESS], arg_type, float_): + yield None + add(action.set_brightness(template_)) if CONF_RED in conf: - add(action.set_red(templatable(conf[CONF_RED], arg_type, float_))) + template_ = None + for template_ in templatable(conf[CONF_RED], arg_type, float_): + yield None + add(action.set_red(template_)) if CONF_GREEN in conf: - add(action.set_green(templatable(conf[CONF_GREEN], arg_type, float_))) + template_ = None + for template_ in templatable(conf[CONF_GREEN], arg_type, float_): + yield None + add(action.set_green(template_)) if CONF_BLUE in conf: - add(action.set_blue(templatable(conf[CONF_BLUE], arg_type, float_))) + template_ = None + for template_ in templatable(conf[CONF_BLUE], arg_type, float_): + yield None + add(action.set_blue(template_)) if CONF_WHITE in conf: - add(action.set_white(templatable(conf[CONF_WHITE], arg_type, float_))) + template_ = None + for template_ in templatable(conf[CONF_WHITE], arg_type, float_): + yield None + add(action.set_white(template_)) if CONF_EFFECT in conf: - add(action.set_effect(templatable(conf[CONF_EFFECT], arg_type, std_string))) - return action + template_ = None + for template_ in templatable(conf[CONF_EFFECT], arg_type, std_string): + yield None + add(action.set_effect(template_)) + yield action elif CONF_SWITCH_TOGGLE in config: conf = config[CONF_SWITCH_TOGGLE] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_toggle_action(template_arg) - return Pvariable(switch.ToggleAction.template(arg_type), config[CONF_ACTION_ID], rhs) + type = switch.ToggleAction.template(arg_type) + yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) elif CONF_SWITCH_TURN_OFF in config: conf = config[CONF_SWITCH_TURN_OFF] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_turn_off_action(template_arg) - return Pvariable(switch.TurnOffAction.template(arg_type), config[CONF_ACTION_ID], rhs) + type = switch.TurnOffAction.template(arg_type) + yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) elif CONF_SWITCH_TURN_ON in config: conf = config[CONF_SWITCH_TURN_ON] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_turn_on_action(template_arg) - return Pvariable(switch.TurnOnAction.template(arg_type), config[CONF_ACTION_ID], rhs) + type = switch.TurnOnAction.template(arg_type) + yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) elif CONF_COVER_OPEN in config: conf = config[CONF_COVER_OPEN] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_open_action(template_arg) - return Pvariable(cover.OpenAction.template(arg_type), config[CONF_ACTION_ID], rhs) + type = cover.OpenAction.template(arg_type) + yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) elif CONF_COVER_CLOSE in config: conf = config[CONF_COVER_CLOSE] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_close_action(template_arg) - return Pvariable(cover.CloseAction.template(arg_type), config[CONF_ACTION_ID], rhs) + type = cover.CloseAction.template(arg_type) + yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) elif CONF_COVER_STOP in config: conf = config[CONF_COVER_STOP] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_stop_action(template_arg) - return Pvariable(cover.StopAction.template(arg_type), config[CONF_ACTION_ID], rhs) + type = cover.StopAction.template(arg_type) + yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) elif CONF_FAN_TOGGLE in config: conf = config[CONF_FAN_TOGGLE] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_toggle_action(template_arg) - return Pvariable(fan.ToggleAction.template(arg_type), config[CONF_ACTION_ID], rhs) + type = fan.ToggleAction.template(arg_type) + yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) elif CONF_FAN_TURN_OFF in config: conf = config[CONF_FAN_TURN_OFF] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_turn_off_action(template_arg) - return Pvariable(fan.TurnOffAction.template(arg_type), config[CONF_ACTION_ID], rhs) + type = fan.TurnOffAction.template(arg_type) + yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) elif CONF_FAN_TURN_ON in config: conf = config[CONF_FAN_TURN_ON] - var = get_variable(conf[CONF_ID]) + for var in get_variable(conf[CONF_ID]): + yield None rhs = var.make_turn_on_action(template_arg) - action = Pvariable(fan.TurnOnAction.template(arg_type), config[CONF_ACTION_ID], rhs) + type = fan.TurnOnAction.template(arg_type) + action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) if CONF_OSCILLATING in config: - add(action.set_oscillating(templatable(conf[CONF_OSCILLATING], arg_type, bool_))) + template_ = None + for template_ in templatable(conf[CONF_OSCILLATING], arg_type, bool_): + yield None + add(action.set_oscillating(template_)) if CONF_SPEED in config: - add(action.set_speed(templatable(conf[CONF_SPEED], arg_type, fan.FanSpeed))) - return action - raise ESPHomeYAMLError(u"Unsupported action {}".format(config)) + template_ = None + for template_ in templatable(conf[CONF_SPEED], arg_type, fan.FanSpeed): + yield None + add(action.set_speed(template_)) + yield action + else: + raise ESPHomeYAMLError(u"Unsupported action {}".format(config)) def build_actions(config, arg_type): - return ArrayInitializer(*[build_action(x, arg_type) for x in config]) + actions = [] + for conf in config: + action = None + for action in build_action(conf, arg_type): + yield None + actions.append(action) + yield ArrayInitializer(*actions) def build_automation(trigger, arg_type, config): rhs = App.make_automation(trigger) - obj = Pvariable(Automation.template(arg_type), config[CONF_AUTOMATION_ID], rhs) + type = Automation.template(arg_type) + obj = Pvariable(config[CONF_AUTOMATION_ID], rhs, type=type) if CONF_IF in config: - add(obj.add_conditions(build_conditions(config[CONF_IF], arg_type))) - add(obj.add_actions(build_actions(config[CONF_THEN], arg_type))) + conditions = None + for conditions in build_conditions(config[CONF_IF], arg_type): + yield + add(obj.add_conditions(conditions)) + actions = None + for actions in build_actions(config[CONF_THEN], arg_type): + yield + add(obj.add_actions(actions)) diff --git a/esphomeyaml/components/ads1115.py b/esphomeyaml/components/ads1115.py index 878ffe237..3acb95a04 100644 --- a/esphomeyaml/components/ads1115.py +++ b/esphomeyaml/components/ads1115.py @@ -12,7 +12,7 @@ ADS1115Component = sensor.sensor_ns.ADS1115Component RATE_REMOVE_MESSAGE = """The rate option has been removed in 1.5.0 and is no longer required.""" ADS1115_SCHEMA = vol.Schema({ - cv.GenerateID('ads1115'): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(ADS1115Component), vol.Required(CONF_ADDRESS): cv.i2c_address, vol.Optional(CONF_RATE): cv.invalid(RATE_REMOVE_MESSAGE) @@ -24,7 +24,7 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [ADS1115_SCHEMA]) def to_code(config): for conf in config: rhs = App.make_ads1115_component(conf[CONF_ADDRESS]) - Pvariable(ADS1115Component, conf[CONF_ID], rhs) + Pvariable(conf[CONF_ID], rhs) BUILD_FLAGS = '-DUSE_ADS1115_SENSOR' diff --git a/esphomeyaml/components/binary_sensor/__init__.py b/esphomeyaml/components/binary_sensor/__init__.py index ec905d68f..406ad11e8 100644 --- a/esphomeyaml/components/binary_sensor/__init__.py +++ b/esphomeyaml/components/binary_sensor/__init__.py @@ -27,18 +27,24 @@ BinarySensor = binary_sensor_ns.BinarySensor MQTTBinarySensorComponent = binary_sensor_ns.MQTTBinarySensorComponent BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({ - cv.GenerateID('mqtt_binary_sensor', CONF_MQTT_ID): cv.register_variable_id, - cv.GenerateID('binary_sensor'): cv.register_variable_id, + cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTBinarySensorComponent), + cv.GenerateID(): cv.declare_variable_id(BinarySensor), vol.Optional(CONF_INVERTED): cv.boolean, vol.Optional(CONF_DEVICE_CLASS): vol.All(vol.Lower, cv.one_of(*DEVICE_CLASSES)), - vol.Optional(CONF_ON_PRESS): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA]), - vol.Optional(CONF_ON_RELEASE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA]), + vol.Optional(CONF_ON_PRESS): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(PressTrigger), + })]), + vol.Optional(CONF_ON_RELEASE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ReleaseTrigger), + })]), vol.Optional(CONF_ON_CLICK): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ClickTrigger), vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds, vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds, })]), vol.Optional(CONF_ON_DOUBLE_CLICK): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(DoubleClickTrigger), vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds, vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds, })]), @@ -53,43 +59,47 @@ def setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config): for conf in config.get(CONF_ON_PRESS, []): rhs = binary_sensor_var.make_press_trigger() - trigger = Pvariable(PressTrigger, conf[CONF_TRIGGER_ID], rhs) - automation.build_automation(trigger, NoArg, conf) + trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) + for _ in automation.build_automation(trigger, NoArg, conf): + yield for conf in config.get(CONF_ON_RELEASE, []): rhs = binary_sensor_var.make_release_trigger() - trigger = Pvariable(ReleaseTrigger, conf[CONF_TRIGGER_ID], rhs) - automation.build_automation(trigger, NoArg, conf) + trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) + for _ in automation.build_automation(trigger, NoArg, conf): + yield for conf in config.get(CONF_ON_CLICK, []): rhs = binary_sensor_var.make_click_trigger(conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH]) - trigger = Pvariable(ClickTrigger, conf[CONF_TRIGGER_ID], rhs) - automation.build_automation(trigger, NoArg, conf) + trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) + for _ in automation.build_automation(trigger, NoArg, conf): + yield for conf in config.get(CONF_ON_DOUBLE_CLICK, []): rhs = binary_sensor_var.make_double_click_trigger(conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH]) - trigger = Pvariable(DoubleClickTrigger, conf[CONF_TRIGGER_ID], rhs) - automation.build_automation(trigger, NoArg, conf) + trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) + for _ in automation.build_automation(trigger, NoArg, conf): + yield setup_mqtt_component(mqtt_var, config) def setup_binary_sensor(binary_sensor_obj, mqtt_obj, config): - binary_sensor_var = Pvariable(BinarySensor, config[CONF_ID], binary_sensor_obj, + binary_sensor_var = Pvariable(config[CONF_ID], binary_sensor_obj, has_side_effects=False) - mqtt_var = Pvariable(MQTTBinarySensorComponent, config[CONF_MQTT_ID], mqtt_obj, + mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) - setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config) + for _ in setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config): + yield def register_binary_sensor(var, config): - binary_sensor_var = Pvariable(BinarySensor, config[CONF_ID], var, - has_side_effects=True) + binary_sensor_var = Pvariable(config[CONF_ID], var, has_side_effects=True) rhs = App.register_binary_sensor(binary_sensor_var) - mqtt_var = Pvariable(MQTTBinarySensorComponent, config[CONF_MQTT_ID], rhs, - has_side_effects=True) - setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config) + mqtt_var = Pvariable(config[CONF_MQTT_ID], rhs, has_side_effects=True) + for _ in setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config): + yield BUILD_FLAGS = '-DUSE_BINARY_SENSOR' diff --git a/esphomeyaml/components/binary_sensor/esp32_ble.py b/esphomeyaml/components/binary_sensor/esp32_ble.py index 0f58c05fa..dc31f7d91 100644 --- a/esphomeyaml/components/binary_sensor/esp32_ble.py +++ b/esphomeyaml/components/binary_sensor/esp32_ble.py @@ -10,6 +10,8 @@ from esphomeyaml.helpers import ArrayInitializer, get_variable ESP_PLATFORMS = [ESP_PLATFORM_ESP32] DEPENDENCIES = ['esp32_ble'] +CONF_ESP32_BLE_ID = 'esp32_ble_id' + def validate_mac(value): value = cv.string_strict(value) @@ -30,14 +32,18 @@ def validate_mac(value): PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ vol.Required(CONF_MAC_ADDRESS): validate_mac, + cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker) }).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema) def to_code(config): - hub = get_variable(None, type=ESP32BLETracker) + hub = None + for hub in get_variable(CONF_ESP32_BLE_ID): + yield addr = [HexInt(i) for i in config[CONF_MAC_ADDRESS].parts] rhs = hub.make_device(config[CONF_NAME], ArrayInitializer(*addr, multiline=False)) - binary_sensor.register_binary_sensor(rhs, config) + for _ in binary_sensor.register_binary_sensor(rhs, config): + yield BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER' diff --git a/esphomeyaml/components/binary_sensor/esp32_touch.py b/esphomeyaml/components/binary_sensor/esp32_touch.py index 321aef22a..b88d75f00 100644 --- a/esphomeyaml/components/binary_sensor/esp32_touch.py +++ b/esphomeyaml/components/binary_sensor/esp32_touch.py @@ -11,6 +11,8 @@ ESP_PLATFORMS = [ESP_PLATFORM_ESP32] DEPENDENCIES = ['esp32_touch'] +CONF_ESP32_TOUCH_ID = 'esp32_touch_id' + TOUCH_PADS = { 4: global_ns.TOUCH_PAD_NUM0, 0: global_ns.TOUCH_PAD_NUM1, @@ -35,14 +37,18 @@ def validate_touch_pad(value): PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ vol.Required(CONF_PIN): validate_touch_pad, vol.Required(CONF_THRESHOLD): cv.uint16_t, + cv.GenerateID(CONF_ESP32_TOUCH_ID): cv.use_variable_id(ESP32TouchComponent), }).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema) def to_code(config): - hub = get_variable(None, type=ESP32TouchComponent) + hub = None + for hub in get_variable(config[CONF_ESP32_TOUCH_ID]): + yield touch_pad = TOUCH_PADS[config[CONF_PIN]] rhs = hub.make_touch_pad(config[CONF_NAME], touch_pad, config[CONF_THRESHOLD]) - binary_sensor.register_binary_sensor(rhs, config) + for _ in binary_sensor.register_binary_sensor(rhs, config): + yield BUILD_FLAGS = '-DUSE_ESP32_TOUCH_BINARY_SENSOR' diff --git a/esphomeyaml/components/binary_sensor/gpio.py b/esphomeyaml/components/binary_sensor/gpio.py index 3da3bde16..5a38409e2 100644 --- a/esphomeyaml/components/binary_sensor/gpio.py +++ b/esphomeyaml/components/binary_sensor/gpio.py @@ -6,19 +6,22 @@ from esphomeyaml.components import binary_sensor from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN from esphomeyaml.helpers import App, gpio_input_pin_expression, variable, Application +MakeGPIOBinarySensor = Application.MakeGPIOBinarySensor + PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('gpio_binary_sensor', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeGPIOBinarySensor), vol.Required(CONF_PIN): pins.GPIO_INPUT_PIN_SCHEMA }).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema) -MakeGPIOBinarySensor = Application.MakeGPIOBinarySensor - def to_code(config): - rhs = App.make_gpio_binary_sensor(config[CONF_NAME], - gpio_input_pin_expression(config[CONF_PIN])) - gpio = variable(MakeGPIOBinarySensor, config[CONF_MAKE_ID], rhs) - binary_sensor.setup_binary_sensor(gpio.Pgpio, gpio.Pmqtt, config) + pin = None + for pin in gpio_input_pin_expression(config[CONF_PIN]): + yield + rhs = App.make_gpio_binary_sensor(config[CONF_NAME], pin) + gpio = variable(config[CONF_MAKE_ID], rhs) + for _ in binary_sensor.setup_binary_sensor(gpio.Pgpio, gpio.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_GPIO_BINARY_SENSOR' diff --git a/esphomeyaml/components/binary_sensor/status.py b/esphomeyaml/components/binary_sensor/status.py index e3c94ec4e..5c305aef3 100644 --- a/esphomeyaml/components/binary_sensor/status.py +++ b/esphomeyaml/components/binary_sensor/status.py @@ -5,17 +5,18 @@ from esphomeyaml.helpers import App, Application, variable DEPENDENCIES = ['mqtt'] -PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('status_binary_sensor', CONF_MAKE_ID): cv.register_variable_id, -}).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema) - MakeStatusBinarySensor = Application.MakeStatusBinarySensor +PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeStatusBinarySensor), +}).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema) + def to_code(config): rhs = App.make_status_binary_sensor(config[CONF_NAME]) - status = variable(MakeStatusBinarySensor, config[CONF_MAKE_ID], rhs) - binary_sensor.setup_binary_sensor(status.Pstatus, status.Pmqtt, config) + status = variable(config[CONF_MAKE_ID], rhs) + for _ in binary_sensor.setup_binary_sensor(status.Pstatus, status.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_STATUS_BINARY_SENSOR' diff --git a/esphomeyaml/components/binary_sensor/template.py b/esphomeyaml/components/binary_sensor/template.py index 70c556ac0..0a6f05667 100644 --- a/esphomeyaml/components/binary_sensor/template.py +++ b/esphomeyaml/components/binary_sensor/template.py @@ -5,19 +5,22 @@ from esphomeyaml.components import binary_sensor from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME from esphomeyaml.helpers import App, Application, process_lambda, variable +MakeTemplateBinarySensor = Application.MakeTemplateBinarySensor + PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('template_binary_sensor', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeTemplateBinarySensor), vol.Required(CONF_LAMBDA): cv.lambda_, }).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema) -MakeTemplateBinarySensor = Application.MakeTemplateBinarySensor - def to_code(config): - template_ = process_lambda(config[CONF_LAMBDA], []) + template_ = None + for template_ in process_lambda(config[CONF_LAMBDA], []): + yield rhs = App.make_template_binary_sensor(config[CONF_NAME], template_) - make = variable(MakeTemplateBinarySensor, config[CONF_MAKE_ID], rhs) - binary_sensor.setup_binary_sensor(make.Ptemplate_, make.Pmqtt, config) + make = variable(config[CONF_MAKE_ID], rhs) + for _ in binary_sensor.setup_binary_sensor(make.Ptemplate_, make.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR' diff --git a/esphomeyaml/components/cover/__init__.py b/esphomeyaml/components/cover/__init__.py index c57ec76c9..a33b1cace 100644 --- a/esphomeyaml/components/cover/__init__.py +++ b/esphomeyaml/components/cover/__init__.py @@ -6,11 +6,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ }) -COVER_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ - cv.GenerateID('cover'): cv.register_variable_id, - cv.GenerateID('mqtt_cover', CONF_MQTT_ID): cv.register_variable_id, -}) - cover_ns = esphomelib_ns.namespace('cover') Cover = cover_ns.Cover MQTTCoverComponent = cover_ns.MQTTCoverComponent @@ -21,15 +16,19 @@ OpenAction = cover_ns.OpenAction CloseAction = cover_ns.CloseAction StopAction = cover_ns.StopAction +COVER_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(Cover), + cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTCoverComponent), +}) + def setup_cover_core_(cover_var, mqtt_var, config): setup_mqtt_component(mqtt_var, config) def setup_cover(cover_obj, mqtt_obj, config): - cover_var = Pvariable(Cover, config[CONF_ID], cover_obj, has_side_effects=False) - mqtt_var = Pvariable(MQTTCoverComponent, config[CONF_MQTT_ID], mqtt_obj, - has_side_effects=False) + cover_var = Pvariable(config[CONF_ID], cover_obj, has_side_effects=False) + mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) setup_cover_core_(cover_var, mqtt_var, config) diff --git a/esphomeyaml/components/cover/template.py b/esphomeyaml/components/cover/template.py index 69009f3d5..4e85bded8 100644 --- a/esphomeyaml/components/cover/template.py +++ b/esphomeyaml/components/cover/template.py @@ -7,8 +7,10 @@ from esphomeyaml.const import CONF_CLOSE_ACTION, CONF_LAMBDA, CONF_MAKE_ID, CONF CONF_OPEN_ACTION, CONF_STOP_ACTION, CONF_OPTIMISTIC from esphomeyaml.helpers import App, Application, NoArg, add, process_lambda, variable +MakeTemplateCover = Application.MakeTemplateCover + PLATFORM_SCHEMA = vol.All(cover.PLATFORM_SCHEMA.extend({ - cv.GenerateID('template_cover', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeTemplateCover), vol.Optional(CONF_LAMBDA): cv.lambda_, vol.Optional(CONF_OPTIMISTIC): cv.boolean, vol.Optional(CONF_OPEN_ACTION): automation.ACTIONS_SCHEMA, @@ -16,24 +18,30 @@ PLATFORM_SCHEMA = vol.All(cover.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_STOP_ACTION): automation.ACTIONS_SCHEMA, }).extend(cover.COVER_SCHEMA.schema), cv.has_at_least_one_key(CONF_LAMBDA, CONF_OPTIMISTIC)) -MakeTemplateCover = Application.MakeTemplateCover - def to_code(config): rhs = App.make_template_cover(config[CONF_NAME]) - make = variable(MakeTemplateCover, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) if CONF_LAMBDA in config: - template_ = process_lambda(config[CONF_LAMBDA], []) + template_ = None + for template_ in process_lambda(config[CONF_LAMBDA], []): + yield add(make.Ptemplate_.set_state_lambda(template_)) if CONF_OPEN_ACTION in config: - actions = automation.build_actions(config[CONF_OPEN_ACTION], NoArg) + actions = None + for actions in automation.build_actions(config[CONF_OPEN_ACTION], NoArg): + yield add(make.Ptemplate_.add_open_actions(actions)) if CONF_CLOSE_ACTION in config: - actions = automation.build_actions(config[CONF_CLOSE_ACTION], NoArg) + actions = None + for actions in automation.build_actions(config[CONF_CLOSE_ACTION], NoArg): + yield add(make.Ptemplate_.add_close_actions(actions)) if CONF_STOP_ACTION in config: - actions = automation.build_actions(config[CONF_STOP_ACTION], NoArg) + actions = None + for actions in automation.build_actions(config[CONF_STOP_ACTION], NoArg): + yield add(make.Ptemplate_.add_stop_actions(actions)) if CONF_OPTIMISTIC in config: add(make.Ptemplate_.set_optimistic(config[CONF_OPTIMISTIC])) diff --git a/esphomeyaml/components/dallas.py b/esphomeyaml/components/dallas.py index 27e5b10e5..440e83b58 100644 --- a/esphomeyaml/components/dallas.py +++ b/esphomeyaml/components/dallas.py @@ -9,7 +9,7 @@ from esphomeyaml.helpers import App, Pvariable DallasComponent = sensor.sensor_ns.DallasComponent CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({ - cv.GenerateID('dallas'): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(DallasComponent), vol.Required(CONF_PIN): pins.input_output_pin, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, })]) @@ -18,7 +18,7 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({ def to_code(config): for conf in config: rhs = App.make_dallas_component(conf[CONF_PIN], conf.get(CONF_UPDATE_INTERVAL)) - Pvariable(DallasComponent, conf[CONF_ID], rhs) + Pvariable(conf[CONF_ID], rhs) BUILD_FLAGS = '-DUSE_DALLAS_SENSOR' diff --git a/esphomeyaml/components/deep_sleep.py b/esphomeyaml/components/deep_sleep.py index 52687d9b2..7459884a9 100644 --- a/esphomeyaml/components/deep_sleep.py +++ b/esphomeyaml/components/deep_sleep.py @@ -14,8 +14,10 @@ def validate_pin_number(value): return value +DeepSleepComponent = esphomelib_ns.DeepSleepComponent + CONFIG_SCHEMA = vol.Schema({ - cv.GenerateID('deep_sleep'): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(DeepSleepComponent), vol.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds, vol.Optional(CONF_WAKEUP_PIN): vol.All(cv.only_on_esp32, pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA, validate_pin_number), @@ -23,16 +25,16 @@ CONFIG_SCHEMA = vol.Schema({ vol.Optional(CONF_RUN_DURATION): cv.positive_time_period_milliseconds, }) -DeepSleepComponent = esphomelib_ns.DeepSleepComponent - def to_code(config): rhs = App.make_deep_sleep_component() - deep_sleep = Pvariable(DeepSleepComponent, config[CONF_ID], rhs) + deep_sleep = Pvariable(config[CONF_ID], rhs) if CONF_SLEEP_DURATION in config: add(deep_sleep.set_sleep_duration(config[CONF_SLEEP_DURATION])) if CONF_WAKEUP_PIN in config: - pin = gpio_input_pin_expression(config[CONF_WAKEUP_PIN]) + pin = None + for pin in gpio_input_pin_expression(config[CONF_WAKEUP_PIN]): + yield add(deep_sleep.set_wakeup_pin(pin)) if CONF_RUN_CYCLES in config: add(deep_sleep.set_run_cycles(config[CONF_RUN_CYCLES])) diff --git a/esphomeyaml/components/esp32_ble.py b/esphomeyaml/components/esp32_ble.py index 5a2620117..c99762b8f 100644 --- a/esphomeyaml/components/esp32_ble.py +++ b/esphomeyaml/components/esp32_ble.py @@ -6,17 +6,17 @@ from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns ESP_PLATFORMS = [ESP_PLATFORM_ESP32] +ESP32BLETracker = esphomelib_ns.ESP32BLETracker + CONFIG_SCHEMA = vol.Schema({ - cv.GenerateID('esp32_ble'): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker), vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds, }) -ESP32BLETracker = esphomelib_ns.ESP32BLETracker - def to_code(config): rhs = App.make_esp32_ble_tracker() - ble = Pvariable(ESP32BLETracker, config[CONF_ID], rhs) + ble = Pvariable(config[CONF_ID], rhs) if CONF_SCAN_INTERVAL in config: add(ble.set_scan_interval(config[CONF_SCAN_INTERVAL])) diff --git a/esphomeyaml/components/esp32_touch.py b/esphomeyaml/components/esp32_touch.py index a89317fc8..2cd08087a 100644 --- a/esphomeyaml/components/esp32_touch.py +++ b/esphomeyaml/components/esp32_touch.py @@ -42,7 +42,6 @@ VOLTAGE_ATTENUATION = { } CONFIG_SCHEMA = vol.Schema({ - cv.GenerateID('esp32_ble'): cv.register_variable_id, vol.Optional(CONF_SETUP_MODE): cv.boolean, vol.Optional(CONF_IIR_FILTER): cv.positive_time_period_milliseconds, vol.Optional(CONF_SLEEP_DURATION): @@ -59,7 +58,7 @@ ESP32TouchComponent = binary_sensor.binary_sensor_ns.ESP32TouchComponent def to_code(config): rhs = App.make_esp32_touch_component() - touch = Pvariable(ESP32TouchComponent, config[CONF_ID], rhs) + touch = Pvariable(config[CONF_ID], rhs) if CONF_SETUP_MODE in config: add(touch.set_setup_mode(config[CONF_SETUP_MODE])) if CONF_IIR_FILTER in config: diff --git a/esphomeyaml/components/fan/__init__.py b/esphomeyaml/components/fan/__init__.py index 8c9f2bfd0..02cd479ac 100644 --- a/esphomeyaml/components/fan/__init__.py +++ b/esphomeyaml/components/fan/__init__.py @@ -9,13 +9,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ }) -FAN_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ - cv.GenerateID('fan'): cv.register_variable_id, - cv.GenerateID('mqtt_fan', CONF_MQTT_ID): cv.register_variable_id, - vol.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.publish_topic, - vol.Optional(CONF_OSCILLATION_COMMAND_TOPIC): cv.subscribe_topic, -}) - fan_ns = esphomelib_ns.namespace('fan') FanState = fan_ns.FanState MQTTFanComponent = fan_ns.MQTTFanComponent @@ -29,6 +22,13 @@ FAN_SPEED_LOW = fan_ns.FAN_SPEED_LOW FAN_SPEED_MEDIUM = fan_ns.FAN_SPEED_MEDIUM FAN_SPEED_HIGH = fan_ns.FAN_SPEED_HIGH +FAN_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(FanState), + cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTFanComponent), + vol.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.publish_topic, + vol.Optional(CONF_OSCILLATION_COMMAND_TOPIC): cv.subscribe_topic, +}) + FAN_SPEEDS = { 'OFF': FAN_SPEED_OFF, @@ -55,8 +55,8 @@ def setup_fan_core_(fan_var, mqtt_var, config): def setup_fan(fan_obj, mqtt_obj, config): - fan_var = Pvariable(FanState, config[CONF_ID], fan_obj, has_side_effects=False) - mqtt_var = Pvariable(MQTTFanComponent, config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) + fan_var = Pvariable(config[CONF_ID], fan_obj, has_side_effects=False) + mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) setup_fan_core_(fan_var, mqtt_var, config) diff --git a/esphomeyaml/components/fan/binary.py b/esphomeyaml/components/fan/binary.py index 8d5a5b912..ab1516d09 100644 --- a/esphomeyaml/components/fan/binary.py +++ b/esphomeyaml/components/fan/binary.py @@ -6,19 +6,24 @@ from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OSCILLATION_OUTPUT, from esphomeyaml.helpers import App, add, get_variable, variable PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({ - cv.GenerateID('binary_fan', CONF_MAKE_ID): cv.register_variable_id, - vol.Required(CONF_OUTPUT): cv.variable_id, - vol.Optional(CONF_OSCILLATION_OUTPUT): cv.variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(fan.MakeFan), + vol.Required(CONF_OUTPUT): cv.use_variable_id(None), + vol.Optional(CONF_OSCILLATION_OUTPUT): cv.use_variable_id(None), }).extend(fan.FAN_SCHEMA.schema) def to_code(config): - output = get_variable(config[CONF_OUTPUT]) + output = None + for output in get_variable(config[CONF_OUTPUT]): + yield + rhs = App.make_fan(config[CONF_NAME]) - fan_struct = variable(fan.MakeFan, config[CONF_MAKE_ID], rhs) + fan_struct = variable(config[CONF_MAKE_ID], rhs) add(fan_struct.Poutput.set_binary(output)) if CONF_OSCILLATION_OUTPUT in config: - oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT]) + oscillation_output = None + for oscillation_output in get_variable(config[CONF_OSCILLATION_OUTPUT]): + yield add(fan_struct.Poutput.set_oscillation(oscillation_output)) fan.setup_fan(fan_struct.Pstate, fan_struct.Pmqtt, config) diff --git a/esphomeyaml/components/fan/speed.py b/esphomeyaml/components/fan/speed.py index 469fe54c6..68fe2e664 100644 --- a/esphomeyaml/components/fan/speed.py +++ b/esphomeyaml/components/fan/speed.py @@ -8,11 +8,11 @@ from esphomeyaml.const import CONF_HIGH, CONF_LOW, CONF_MAKE_ID, CONF_MEDIUM, CO from esphomeyaml.helpers import App, add, get_variable, variable PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({ - cv.GenerateID('speed_fan', CONF_MAKE_ID): cv.register_variable_id, - vol.Required(CONF_OUTPUT): cv.variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(fan.MakeFan), + vol.Required(CONF_OUTPUT): cv.use_variable_id(None), vol.Optional(CONF_SPEED_STATE_TOPIC): cv.publish_topic, vol.Optional(CONF_SPEED_COMMAND_TOPIC): cv.subscribe_topic, - vol.Optional(CONF_OSCILLATION_OUTPUT): cv.variable_id, + vol.Optional(CONF_OSCILLATION_OUTPUT): cv.use_variable_id(None), vol.Optional(CONF_SPEED): vol.Schema({ vol.Required(CONF_LOW): cv.percentage, vol.Required(CONF_MEDIUM): cv.percentage, @@ -22,9 +22,11 @@ PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({ def to_code(config): - output = get_variable(config[CONF_OUTPUT]) + output = None + for output in get_variable(config[CONF_OUTPUT]): + yield rhs = App.make_fan(config[CONF_NAME]) - fan_struct = variable(fan.MakeFan, config[CONF_MAKE_ID], rhs) + fan_struct = variable(config[CONF_MAKE_ID], rhs) if CONF_SPEED in config: speeds = config[CONF_SPEED] add(fan_struct.Poutput.set_speed(output, 0.0, @@ -35,7 +37,9 @@ def to_code(config): add(fan_struct.Poutput.set_speed(output)) if CONF_OSCILLATION_OUTPUT in config: - oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT]) + oscillation_output = None + for oscillation_output in get_variable(config[CONF_OSCILLATION_OUTPUT]): + yield add(fan_struct.Poutput.set_oscillation(oscillation_output)) fan.setup_fan(fan_struct.Pstate, fan_struct.Pmqtt, config) diff --git a/esphomeyaml/components/i2c.py b/esphomeyaml/components/i2c.py index b3b563d9b..41e54f601 100644 --- a/esphomeyaml/components/i2c.py +++ b/esphomeyaml/components/i2c.py @@ -6,8 +6,10 @@ from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CON CONF_RECEIVE_TIMEOUT from esphomeyaml.helpers import App, add, Pvariable, esphomelib_ns +I2CComponent = esphomelib_ns.I2CComponent + CONFIG_SCHEMA = vol.Schema({ - cv.GenerateID('i2c'): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(I2CComponent), vol.Required(CONF_SDA, default='SDA'): pins.input_output_pin, vol.Required(CONF_SCL, default='SCL'): pins.input_output_pin, vol.Optional(CONF_FREQUENCY): cv.positive_int, @@ -15,12 +17,10 @@ CONFIG_SCHEMA = vol.Schema({ vol.Optional(CONF_SCAN): cv.boolean, }) -I2CComponent = esphomelib_ns.I2CComponent - def to_code(config): rhs = App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_SCAN)) - i2c = Pvariable(I2CComponent, config[CONF_ID], rhs) + i2c = Pvariable(config[CONF_ID], rhs) if CONF_FREQUENCY in config: add(i2c.set_frequency(config[CONF_FREQUENCY])) if CONF_RECEIVE_TIMEOUT in config: diff --git a/esphomeyaml/components/ir_transmitter.py b/esphomeyaml/components/ir_transmitter.py index 7ac2af7bc..9ea5cb374 100644 --- a/esphomeyaml/components/ir_transmitter.py +++ b/esphomeyaml/components/ir_transmitter.py @@ -6,21 +6,23 @@ from esphomeyaml.components import switch from esphomeyaml.const import CONF_CARRIER_DUTY_PERCENT, CONF_ID, CONF_PIN from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression +IRTransmitterComponent = switch.switch_ns.namespace('IRTransmitterComponent') + CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({ - cv.GenerateID('ir_transmitter'): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(IRTransmitterComponent), vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Optional(CONF_CARRIER_DUTY_PERCENT): vol.All(vol.Coerce(int), vol.Range(min=1, max=100)), })]) -IRTransmitterComponent = switch.switch_ns.namespace('IRTransmitterComponent') - def to_code(config): for conf in config: - pin = gpio_output_pin_expression(conf[CONF_PIN]) + pin = None + for pin in gpio_output_pin_expression(conf[CONF_PIN]): + yield rhs = App.make_ir_transmitter(pin, conf.get(CONF_CARRIER_DUTY_PERCENT)) - Pvariable(IRTransmitterComponent, conf[CONF_ID], rhs) + Pvariable(conf[CONF_ID], rhs) BUILD_FLAGS = '-DUSE_IR_TRANSMITTER' diff --git a/esphomeyaml/components/light/__init__.py b/esphomeyaml/components/light/__init__.py index e6669c7e7..6ce4567ef 100644 --- a/esphomeyaml/components/light/__init__.py +++ b/esphomeyaml/components/light/__init__.py @@ -7,11 +7,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ }) -LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ - cv.GenerateID('light'): cv.register_variable_id, - cv.GenerateID('mqtt_light', CONF_MQTT_ID): cv.register_variable_id, -}) - light_ns = esphomelib_ns.namespace('light') LightState = light_ns.LightState MQTTJSONLightComponent = light_ns.MQTTJSONLightComponent @@ -20,6 +15,11 @@ TurnOffAction = light_ns.TurnOffAction TurnOnAction = light_ns.TurnOnAction MakeLight = Application.MakeLight +LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(LightState), + cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTJSONLightComponent), +}) + def setup_light_core_(light_var, mqtt_var, config): if CONF_DEFAULT_TRANSITION_LENGTH in config: @@ -31,9 +31,8 @@ def setup_light_core_(light_var, mqtt_var, config): def setup_light(light_obj, mqtt_obj, config): - light_var = Pvariable(LightState, config[CONF_ID], light_obj, has_side_effects=False) - mqtt_var = Pvariable(MQTTJSONLightComponent, config[CONF_MQTT_ID], mqtt_obj, - has_side_effects=False) + light_var = Pvariable(config[CONF_ID], light_obj, has_side_effects=False) + mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) setup_light_core_(light_var, mqtt_var, config) diff --git a/esphomeyaml/components/light/binary.py b/esphomeyaml/components/light/binary.py index a469f5e93..6a9283702 100644 --- a/esphomeyaml/components/light/binary.py +++ b/esphomeyaml/components/light/binary.py @@ -6,13 +6,15 @@ from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT from esphomeyaml.helpers import App, get_variable, variable PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ - cv.GenerateID('binary_light', CONF_MAKE_ID): cv.register_variable_id, - vol.Required(CONF_OUTPUT): cv.variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), + vol.Required(CONF_OUTPUT): cv.use_variable_id(None), }).extend(light.LIGHT_SCHEMA.schema) def to_code(config): - output = get_variable(config[CONF_OUTPUT]) + output = None + for output in get_variable(config[CONF_OUTPUT]): + yield rhs = App.make_binary_light(config[CONF_NAME], output) - light_struct = variable(light.MakeLight, config[CONF_MAKE_ID], rhs) + light_struct = variable(config[CONF_MAKE_ID], rhs) light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config) diff --git a/esphomeyaml/components/light/fastled_clockless.py b/esphomeyaml/components/light/fastled_clockless.py index afaabffa0..878254bde 100644 --- a/esphomeyaml/components/light/fastled_clockless.py +++ b/esphomeyaml/components/light/fastled_clockless.py @@ -3,6 +3,7 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import light +from esphomeyaml.components.power_supply import PowerSupplyComponent from esphomeyaml.const import CONF_CHIPSET, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, \ CONF_RGB_ORDER @@ -52,8 +53,10 @@ def validate(value): return value +MakeFastLEDLight = Application.MakeFastLEDLight + PLATFORM_SCHEMA = vol.All(light.PLATFORM_SCHEMA.extend({ - cv.GenerateID('fast_led_clockless_light', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeFastLEDLight), vol.Required(CONF_CHIPSET): vol.All(vol.Upper, cv.one_of(*TYPES)), vol.Required(CONF_PIN): pins.output_pin, @@ -64,15 +67,13 @@ PLATFORM_SCHEMA = vol.All(light.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, - vol.Optional(CONF_POWER_SUPPLY): cv.variable_id, + vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent), }).extend(light.LIGHT_SCHEMA.schema), validate) -MakeFastLEDLight = Application.MakeFastLEDLight - def to_code(config): rhs = App.make_fast_led_light(config[CONF_NAME]) - make = variable(MakeFastLEDLight, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) fast_led = make.Pfast_led rgb_order = None @@ -86,7 +87,9 @@ def to_code(config): add(fast_led.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE])) if CONF_POWER_SUPPLY in config: - power_supply = get_variable(config[CONF_POWER_SUPPLY]) + power_supply = None + for power_supply in get_variable(config[CONF_POWER_SUPPLY]): + yield add(fast_led.set_power_supply(power_supply)) light.setup_light(make.Pstate, make.Pmqtt, config) diff --git a/esphomeyaml/components/light/fastled_spi.py b/esphomeyaml/components/light/fastled_spi.py index 54be4f7d4..84d848dbf 100644 --- a/esphomeyaml/components/light/fastled_spi.py +++ b/esphomeyaml/components/light/fastled_spi.py @@ -3,6 +3,7 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import light +from esphomeyaml.components.power_supply import PowerSupplyComponent from esphomeyaml.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_DATA_PIN, \ CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, \ CONF_NAME, CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER @@ -29,8 +30,10 @@ RGB_ORDERS = [ 'BGR', ] +MakeFastLEDLight = Application.MakeFastLEDLight + PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ - cv.GenerateID('fast_led_spi_light', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeFastLEDLight), vol.Required(CONF_CHIPSET): vol.All(vol.Upper, cv.one_of(*CHIPSETS)), vol.Required(CONF_DATA_PIN): pins.output_pin, @@ -42,15 +45,13 @@ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, - vol.Optional(CONF_POWER_SUPPLY): cv.variable_id, + vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent), }).extend(light.LIGHT_SCHEMA.schema) -MakeFastLEDLight = Application.MakeFastLEDLight - def to_code(config): rhs = App.make_fast_led_light(config[CONF_NAME]) - make = variable(MakeFastLEDLight, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) fast_led = make.Pfast_led rgb_order = None @@ -66,7 +67,9 @@ def to_code(config): add(fast_led.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE])) if CONF_POWER_SUPPLY in config: - power_supply = get_variable(config[CONF_POWER_SUPPLY]) + power_supply = None + for power_supply in get_variable(config[CONF_POWER_SUPPLY]): + yield add(fast_led.set_power_supply(power_supply)) light.setup_light(make.Pstate, make.Pmqtt, config) diff --git a/esphomeyaml/components/light/monochromatic.py b/esphomeyaml/components/light/monochromatic.py index af5422d3f..75a8a9a71 100644 --- a/esphomeyaml/components/light/monochromatic.py +++ b/esphomeyaml/components/light/monochromatic.py @@ -7,15 +7,17 @@ from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT from esphomeyaml.helpers import App, get_variable, variable PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ - cv.GenerateID('monochromatic_light', CONF_MAKE_ID): cv.register_variable_id, - vol.Required(CONF_OUTPUT): cv.variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), + vol.Required(CONF_OUTPUT): cv.use_variable_id(None), vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, }).extend(light.LIGHT_SCHEMA.schema) def to_code(config): - output = get_variable(config[CONF_OUTPUT]) + output = None + for output in get_variable(config[CONF_OUTPUT]): + yield rhs = App.make_monochromatic_light(config[CONF_NAME], output) - light_struct = variable(light.MakeLight, config[CONF_MAKE_ID], rhs) + light_struct = variable(config[CONF_MAKE_ID], rhs) light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config) diff --git a/esphomeyaml/components/light/rgb.py b/esphomeyaml/components/light/rgb.py index 83b6f8dab..1506fa957 100644 --- a/esphomeyaml/components/light/rgb.py +++ b/esphomeyaml/components/light/rgb.py @@ -7,19 +7,25 @@ from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GA from esphomeyaml.helpers import App, get_variable, variable PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ - cv.GenerateID('rgb_light', CONF_MAKE_ID): cv.register_variable_id, - vol.Required(CONF_RED): cv.variable_id, - vol.Required(CONF_GREEN): cv.variable_id, - vol.Required(CONF_BLUE): cv.variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), + vol.Required(CONF_RED): cv.use_variable_id(None), + vol.Required(CONF_GREEN): cv.use_variable_id(None), + vol.Required(CONF_BLUE): cv.use_variable_id(None), vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, }).extend(light.LIGHT_SCHEMA.schema) def to_code(config): - red = get_variable(config[CONF_RED]) - green = get_variable(config[CONF_GREEN]) - blue = get_variable(config[CONF_BLUE]) + red = None + for red in get_variable(config[CONF_RED]): + yield + green = None + for green in get_variable(config[CONF_GREEN]): + yield + blue = None + for blue in get_variable(config[CONF_BLUE]): + yield rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue) - light_struct = variable(light.MakeLight, config[CONF_MAKE_ID], rhs) + light_struct = variable(config[CONF_MAKE_ID], rhs) light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config) diff --git a/esphomeyaml/components/light/rgbw.py b/esphomeyaml/components/light/rgbw.py index cdbfc8828..8617db5bc 100644 --- a/esphomeyaml/components/light/rgbw.py +++ b/esphomeyaml/components/light/rgbw.py @@ -7,21 +7,29 @@ from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GA from esphomeyaml.helpers import App, get_variable, variable PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ - cv.GenerateID('rgbw_light', CONF_MAKE_ID): cv.register_variable_id, - vol.Required(CONF_RED): cv.variable_id, - vol.Required(CONF_GREEN): cv.variable_id, - vol.Required(CONF_BLUE): cv.variable_id, - vol.Required(CONF_WHITE): cv.variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), + vol.Required(CONF_RED): cv.use_variable_id(None), + vol.Required(CONF_GREEN): cv.use_variable_id(None), + vol.Required(CONF_BLUE): cv.use_variable_id(None), + vol.Required(CONF_WHITE): cv.use_variable_id(None), vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, }).extend(light.LIGHT_SCHEMA.schema) def to_code(config): - red = get_variable(config[CONF_RED]) - green = get_variable(config[CONF_GREEN]) - blue = get_variable(config[CONF_BLUE]) - white = get_variable(config[CONF_WHITE]) + red = None + for red in get_variable(config[CONF_RED]): + yield + green = None + for green in get_variable(config[CONF_GREEN]): + yield + blue = None + for blue in get_variable(config[CONF_BLUE]): + yield + white = None + for white in get_variable(config[CONF_WHITE]): + yield rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white) - light_struct = variable(light.MakeLight, config[CONF_MAKE_ID], rhs) + light_struct = variable(config[CONF_MAKE_ID], rhs) light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config) diff --git a/esphomeyaml/components/logger.py b/esphomeyaml/components/logger.py index a48956042..6741ca95f 100644 --- a/esphomeyaml/components/logger.py +++ b/esphomeyaml/components/logger.py @@ -1,7 +1,7 @@ import voluptuous as vol import esphomeyaml.config_validation as cv -from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGGER, CONF_LOGS, \ +from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGS, \ CONF_TX_BUFFER_SIZE from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, global_ns @@ -31,8 +31,10 @@ def validate_local_no_higher_than_global(value): return value +LogComponent = esphomelib_ns.LogComponent + CONFIG_SCHEMA = vol.All(vol.Schema({ - cv.GenerateID(CONF_LOGGER): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(LogComponent), vol.Optional(CONF_BAUD_RATE): cv.positive_int, vol.Optional(CONF_TX_BUFFER_SIZE): cv.positive_int, vol.Optional(CONF_LEVEL): is_log_level, @@ -41,12 +43,10 @@ CONFIG_SCHEMA = vol.All(vol.Schema({ }) }), validate_local_no_higher_than_global) -LogComponent = esphomelib_ns.LogComponent - def to_code(config): rhs = App.init_log(config.get(CONF_BAUD_RATE)) - log = Pvariable(LogComponent, config[CONF_ID], rhs) + log = Pvariable(config[CONF_ID], rhs) if CONF_TX_BUFFER_SIZE in config: add(log.set_tx_buffer_size(config[CONF_TX_BUFFER_SIZE])) if CONF_LEVEL in config: diff --git a/esphomeyaml/components/mqtt.py b/esphomeyaml/components/mqtt.py index 8ae4725a3..484d74b86 100644 --- a/esphomeyaml/components/mqtt.py +++ b/esphomeyaml/components/mqtt.py @@ -6,11 +6,12 @@ import esphomeyaml.config_validation as cv from esphomeyaml import automation from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, CONF_DISCOVERY, \ CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_KEEPALIVE, CONF_LOG_TOPIC, \ - CONF_MQTT, CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, \ + CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, \ CONF_SSL_FINGERPRINTS, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, \ CONF_WILL_MESSAGE -from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, StructInitializer, \ - TemplateArguments, add, esphomelib_ns, optional, std_string, RawExpression +from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \ + StructInitializer, \ + TemplateArguments, add, esphomelib_ns, optional, std_string def validate_message_just_topic(value): @@ -54,7 +55,7 @@ def validate_fingerprint(value): CONFIG_SCHEMA = vol.Schema({ - cv.GenerateID(CONF_MQTT): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(MQTTClientComponent), vol.Required(CONF_BROKER): validate_broker, vol.Optional(CONF_PORT, default=1883): cv.port, vol.Optional(CONF_USERNAME, default=''): cv.string, @@ -71,6 +72,7 @@ CONFIG_SCHEMA = vol.Schema({ cv.ensure_list, [validate_fingerprint]), vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds, vol.Optional(CONF_ON_MESSAGE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger), vol.Required(CONF_TOPIC): cv.publish_topic, vol.Optional(CONF_QOS, 0): cv.mqtt_qos, })]) @@ -93,7 +95,7 @@ def exp_mqtt_message(config): def to_code(config): rhs = App.init_mqtt(config[CONF_BROKER], config[CONF_PORT], config[CONF_USERNAME], config[CONF_PASSWORD]) - mqtt = Pvariable(MQTTClientComponent, config[CONF_ID], rhs) + mqtt = Pvariable(config[CONF_ID], rhs) if not config.get(CONF_DISCOVERY, True): add(mqtt.disable_discovery()) if CONF_DISCOVERY_RETAIN in config or CONF_DISCOVERY_PREFIX in config: @@ -131,8 +133,9 @@ def to_code(config): for conf in config.get(CONF_ON_MESSAGE, []): rhs = mqtt.make_message_trigger(conf[CONF_TOPIC], conf[CONF_QOS]) - trigger = Pvariable(MQTTMessageTrigger, conf[CONF_TRIGGER_ID], rhs) - automation.build_automation(trigger, std_string, conf) + trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) + for _ in automation.build_automation(trigger, std_string, conf): + yield def required_build_flags(config): diff --git a/esphomeyaml/components/ota.py b/esphomeyaml/components/ota.py index 7398202ec..9fb86d6cf 100644 --- a/esphomeyaml/components/ota.py +++ b/esphomeyaml/components/ota.py @@ -12,20 +12,20 @@ from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns _LOGGER = logging.getLogger(__name__) +OTAComponent = esphomelib_ns.OTAComponent + CONFIG_SCHEMA = vol.Schema({ - cv.GenerateID(CONF_OTA): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(OTAComponent), vol.Optional(CONF_SAFE_MODE, default=True): cv.boolean, # TODO Num attempts + wait time vol.Optional(CONF_PORT): cv.port, vol.Optional(CONF_PASSWORD): cv.string, }) -OTAComponent = esphomelib_ns.OTAComponent - def to_code(config): rhs = App.init_ota() - ota = Pvariable(OTAComponent, config[CONF_ID], rhs) + ota = Pvariable(config[CONF_ID], rhs) if CONF_PASSWORD in config: hash_ = hashlib.md5(config[CONF_PASSWORD].encode()).hexdigest() add(ota.set_auth_password_hash(hash_)) diff --git a/esphomeyaml/components/output/__init__.py b/esphomeyaml/components/output/__init__.py index d1717d3fa..cb8dda9d1 100644 --- a/esphomeyaml/components/output/__init__.py +++ b/esphomeyaml/components/output/__init__.py @@ -1,6 +1,7 @@ import voluptuous as vol import esphomeyaml.config_validation as cv +from esphomeyaml.components.power_supply import PowerSupplyComponent from esphomeyaml.const import CONF_INVERTED, CONF_MAX_POWER, CONF_POWER_SUPPLY from esphomeyaml.helpers import add, esphomelib_ns, get_variable @@ -8,8 +9,8 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ }) -BINARY_OUTPUT_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({ - vol.Optional(CONF_POWER_SUPPLY): cv.variable_id, +BINARY_OUTPUT_SCHEMA = vol.Schema({ + vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent), vol.Optional(CONF_INVERTED): cv.boolean, }) @@ -24,7 +25,9 @@ def setup_output_platform(obj, config, skip_power_supply=False): if CONF_INVERTED in config: add(obj.set_inverted(config[CONF_INVERTED])) if not skip_power_supply and CONF_POWER_SUPPLY in config: - power_supply = get_variable(config[CONF_POWER_SUPPLY]) + power_supply = None + for power_supply in get_variable(config[CONF_POWER_SUPPLY]): + yield add(obj.set_power_supply(power_supply)) if CONF_MAX_POWER in config: add(obj.set_max_power(config[CONF_MAX_POWER])) diff --git a/esphomeyaml/components/output/esp8266_pwm.py b/esphomeyaml/components/output/esp8266_pwm.py index c457062e6..07cb57b66 100644 --- a/esphomeyaml/components/output/esp8266_pwm.py +++ b/esphomeyaml/components/output/esp8266_pwm.py @@ -1,8 +1,9 @@ import voluptuous as vol from esphomeyaml import pins +import esphomeyaml.config_validation as cv from esphomeyaml.components import output -from esphomeyaml.const import CONF_ID, CONF_PIN, ESP_PLATFORM_ESP8266, CONF_NUMBER +from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_PIN, ESP_PLATFORM_ESP8266 from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression @@ -15,17 +16,20 @@ def valid_pwm_pin(value): return value +ESP8266PWMOutput = output.output_ns.ESP8266PWMOutput + PLATFORM_SCHEMA = output.PLATFORM_SCHEMA.extend({ + vol.Required(CONF_ID): cv.declare_variable_id(ESP8266PWMOutput), vol.Required(CONF_PIN): vol.All(pins.GPIO_INTERNAL_OUTPUT_PIN_SCHEMA, valid_pwm_pin), }).extend(output.FLOAT_OUTPUT_SCHEMA.schema) -ESP8266PWMOutput = output.output_ns.ESP8266PWMOutput - def to_code(config): - pin = gpio_output_pin_expression(config[CONF_PIN]) + pin = None + for pin in gpio_output_pin_expression(config[CONF_PIN]): + yield rhs = App.make_esp8266_pwm_output(pin) - gpio = Pvariable(ESP8266PWMOutput, config[CONF_ID], rhs) + gpio = Pvariable(config[CONF_ID], rhs) output.setup_output_platform(gpio, config) diff --git a/esphomeyaml/components/output/gpio.py b/esphomeyaml/components/output/gpio.py index c82a551d2..4315d1648 100644 --- a/esphomeyaml/components/output/gpio.py +++ b/esphomeyaml/components/output/gpio.py @@ -1,21 +1,25 @@ import voluptuous as vol from esphomeyaml import pins +import esphomeyaml.config_validation as cv from esphomeyaml.components import output from esphomeyaml.const import CONF_ID, CONF_PIN from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression +GPIOBinaryOutputComponent = output.output_ns.GPIOBinaryOutputComponent + PLATFORM_SCHEMA = output.PLATFORM_SCHEMA.extend({ + vol.Required(CONF_ID): cv.declare_variable_id(GPIOBinaryOutputComponent), vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, }).extend(output.BINARY_OUTPUT_SCHEMA.schema) -GPIOBinaryOutputComponent = output.output_ns.GPIOBinaryOutputComponent - def to_code(config): - pin = gpio_output_pin_expression(config[CONF_PIN]) + pin = None + for pin in gpio_output_pin_expression(config[CONF_PIN]): + yield rhs = App.make_gpio_output(pin) - gpio = Pvariable(GPIOBinaryOutputComponent, config[CONF_ID], rhs) + gpio = Pvariable(config[CONF_ID], rhs) output.setup_output_platform(gpio, config) diff --git a/esphomeyaml/components/output/ledc.py b/esphomeyaml/components/output/ledc.py index dbe434411..60488e364 100644 --- a/esphomeyaml/components/output/ledc.py +++ b/esphomeyaml/components/output/ledc.py @@ -19,7 +19,10 @@ def validate_frequency_bit_depth(obj): return obj +LEDCOutputComponent = output.output_ns.LEDCOutputComponent + PLATFORM_SCHEMA = vol.All(output.PLATFORM_SCHEMA.extend({ + vol.Required(CONF_ID): cv.declare_variable_id(LEDCOutputComponent), vol.Required(CONF_PIN): pins.output_pin, vol.Optional(CONF_FREQUENCY): cv.frequency, vol.Optional(CONF_BIT_DEPTH): vol.All(vol.Coerce(int), vol.Range(min=1, max=15)), @@ -27,15 +30,12 @@ PLATFORM_SCHEMA = vol.All(output.PLATFORM_SCHEMA.extend({ }).extend(output.FLOAT_OUTPUT_SCHEMA.schema), validate_frequency_bit_depth) -LEDCOutputComponent = output.output_ns.LEDCOutputComponent - - def to_code(config): frequency = config.get(CONF_FREQUENCY) if frequency is None and CONF_BIT_DEPTH in config: frequency = 1000 rhs = App.make_ledc_output(config[CONF_PIN], frequency, config.get(CONF_BIT_DEPTH)) - ledc = Pvariable(LEDCOutputComponent, config[CONF_ID], rhs) + ledc = Pvariable(config[CONF_ID], rhs) if CONF_CHANNEL in config: add(ledc.set_channel(config[CONF_CHANNEL])) output.setup_output_platform(ledc, config) diff --git a/esphomeyaml/components/output/pca9685.py b/esphomeyaml/components/output/pca9685.py index 1d617efa7..dbb2a2fec 100644 --- a/esphomeyaml/components/output/pca9685.py +++ b/esphomeyaml/components/output/pca9685.py @@ -8,22 +8,26 @@ from esphomeyaml.helpers import Pvariable, get_variable DEPENDENCIES = ['pca9685'] +Channel = PCA9685OutputComponent.Channel + PLATFORM_SCHEMA = output.PLATFORM_SCHEMA.extend({ + vol.Required(CONF_ID): cv.declare_variable_id(Channel), vol.Required(CONF_CHANNEL): vol.All(vol.Coerce(int), vol.Range(min=0, max=15)), - vol.Optional(CONF_PCA9685_ID): cv.variable_id, + cv.GenerateID(CONF_PCA9685_ID): cv.use_variable_id(PCA9685OutputComponent), }).extend(output.FLOAT_OUTPUT_SCHEMA.schema) -Channel = PCA9685OutputComponent.Channel - def to_code(config): power_supply = None if CONF_POWER_SUPPLY in config: - power_supply = get_variable(config[CONF_POWER_SUPPLY]) - pca9685 = get_variable(config.get(CONF_PCA9685_ID), PCA9685OutputComponent) + for power_supply in get_variable(config[CONF_POWER_SUPPLY]): + yield + pca9685 = None + for pca9685 in get_variable(config[CONF_PCA9685_ID]): + yield rhs = pca9685.create_channel(config[CONF_CHANNEL], power_supply) - out = Pvariable(Channel, config[CONF_ID], rhs) + out = Pvariable(config[CONF_ID], rhs) output.setup_output_platform(out, config, skip_power_supply=True) diff --git a/esphomeyaml/components/pca9685.py b/esphomeyaml/components/pca9685.py index d1a9c59c3..b2a3f2b09 100644 --- a/esphomeyaml/components/pca9685.py +++ b/esphomeyaml/components/pca9685.py @@ -13,7 +13,7 @@ PHASE_BALANCER_MESSAGE = ("The phase_balancer option has been removed in version "esphomelib will now automatically choose a suitable phase balancer.") PCA9685_SCHEMA = vol.Schema({ - cv.GenerateID('pca9685'): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(PCA9685OutputComponent), vol.Required(CONF_FREQUENCY): vol.All(cv.frequency, vol.Range(min=23.84, max=1525.88)), vol.Optional(CONF_ADDRESS): cv.i2c_address, @@ -27,7 +27,7 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCA9685_SCHEMA]) def to_code(config): for conf in config: rhs = App.make_pca9685_component(conf.get(CONF_FREQUENCY)) - pca9685 = Pvariable(PCA9685OutputComponent, conf[CONF_ID], rhs) + pca9685 = Pvariable(conf[CONF_ID], rhs) if CONF_ADDRESS in conf: add(pca9685.set_address(HexIntLiteral(conf[CONF_ADDRESS]))) diff --git a/esphomeyaml/components/pcf8574.py b/esphomeyaml/components/pcf8574.py index 8f10226fa..9a1d40f84 100644 --- a/esphomeyaml/components/pcf8574.py +++ b/esphomeyaml/components/pcf8574.py @@ -6,22 +6,22 @@ from esphomeyaml.helpers import App, Pvariable, esphomelib_ns DEPENDENCIES = ['i2c'] +io_ns = esphomelib_ns.namespace('io') +PCF8574Component = io_ns.PCF8574Component + PCF8574_SCHEMA = vol.Schema({ - vol.Required(CONF_ID): cv.register_variable_id, + vol.Required(CONF_ID): cv.declare_variable_id(PCF8574Component), vol.Optional(CONF_ADDRESS, default=0x21): cv.i2c_address, vol.Optional(CONF_PCF8575, default=False): cv.boolean, }) CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCF8574_SCHEMA]) -io_ns = esphomelib_ns.namespace('io') -PCF8574Component = io_ns.PCF8574Component - def to_code(config): for conf in config: rhs = App.make_pcf8574_component(conf[CONF_ADDRESS], conf[CONF_PCF8575]) - Pvariable(PCF8574Component, conf[CONF_ID], rhs) + Pvariable(conf[CONF_ID], rhs) BUILD_FLAGS = '-DUSE_PCF8574' diff --git a/esphomeyaml/components/power_supply.py b/esphomeyaml/components/power_supply.py index e6aee6eda..253efedc6 100644 --- a/esphomeyaml/components/power_supply.py +++ b/esphomeyaml/components/power_supply.py @@ -5,7 +5,10 @@ from esphomeyaml import pins from esphomeyaml.const import CONF_ENABLE_TIME, CONF_ID, CONF_KEEP_ON_TIME, CONF_PIN from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_output_pin_expression -POWER_SUPPLY_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({ +PowerSupplyComponent = esphomelib_ns.PowerSupplyComponent + +POWER_SUPPLY_SCHEMA = vol.Schema({ + vol.Required(CONF_ID): cv.declare_variable_id(PowerSupplyComponent), vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Optional(CONF_ENABLE_TIME): cv.positive_time_period_milliseconds, vol.Optional(CONF_KEEP_ON_TIME): cv.positive_time_period_milliseconds, @@ -13,13 +16,14 @@ POWER_SUPPLY_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({ CONFIG_SCHEMA = vol.All(cv.ensure_list, [POWER_SUPPLY_SCHEMA]) -PowerSupplyComponent = esphomelib_ns.PowerSupplyComponent - def to_code(config): for conf in config: - rhs = App.make_power_supply(gpio_output_pin_expression(conf[CONF_PIN])) - psu = Pvariable(PowerSupplyComponent, conf[CONF_ID], rhs) + pin = None + for pin in gpio_output_pin_expression(conf[CONF_PIN]): + yield + rhs = App.make_power_supply(pin) + psu = Pvariable(conf[CONF_ID], rhs) if CONF_ENABLE_TIME in conf: add(psu.set_enable_time(conf[CONF_ENABLE_TIME])) if CONF_KEEP_ON_TIME in conf: diff --git a/esphomeyaml/components/sensor/__init__.py b/esphomeyaml/components/sensor/__init__.py index 5ae57f3d7..905c1b07a 100644 --- a/esphomeyaml/components/sensor/__init__.py +++ b/esphomeyaml/components/sensor/__init__.py @@ -46,24 +46,6 @@ FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({ vol.Optional(CONF_OR): validate_recursive_filter, }, cv.has_exactly_one_key(*FILTER_KEYS))]) -SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({ - cv.GenerateID('mqtt_sensor', CONF_MQTT_ID): cv.register_variable_id, - cv.GenerateID('sensor'): cv.register_variable_id, - vol.Required(CONF_NAME): cv.string, - vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict, - vol.Optional(CONF_ICON): cv.icon, - vol.Optional(CONF_ACCURACY_DECIMALS): vol.Coerce(int), - vol.Optional(CONF_EXPIRE_AFTER): vol.Any(None, cv.positive_time_period_milliseconds), - vol.Optional(CONF_FILTERS): FILTERS_SCHEMA, - vol.Optional(CONF_ON_VALUE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA]), - vol.Optional(CONF_ON_RAW_VALUE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA]), - vol.Optional(CONF_ON_VALUE_RANGE): vol.All(cv.ensure_list, [vol.All( - automation.AUTOMATION_SCHEMA.extend({ - vol.Optional(CONF_ABOVE): vol.Coerce(float), - vol.Optional(CONF_BELOW): vol.Coerce(float), - }), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW))]), -}) - # pylint: disable=invalid-name sensor_ns = esphomelib_ns.namespace('sensor') Sensor = sensor_ns.Sensor @@ -86,41 +68,72 @@ SensorValueTrigger = sensor_ns.SensorValueTrigger RawSensorValueTrigger = sensor_ns.RawSensorValueTrigger ValueRangeTrigger = sensor_ns.ValueRangeTrigger +SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({ + cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTSensorComponent), + cv.GenerateID(): cv.declare_variable_id(Sensor), + vol.Required(CONF_NAME): cv.string, + vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict, + vol.Optional(CONF_ICON): cv.icon, + vol.Optional(CONF_ACCURACY_DECIMALS): vol.Coerce(int), + vol.Optional(CONF_EXPIRE_AFTER): vol.Any(None, cv.positive_time_period_milliseconds), + vol.Optional(CONF_FILTERS): FILTERS_SCHEMA, + vol.Optional(CONF_ON_VALUE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(SensorValueTrigger), + })]), + vol.Optional(CONF_ON_RAW_VALUE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(RawSensorValueTrigger), + })]), + vol.Optional(CONF_ON_VALUE_RANGE): vol.All(cv.ensure_list, [vol.All( + automation.AUTOMATION_SCHEMA.extend({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ValueRangeTrigger), + vol.Optional(CONF_ABOVE): vol.Coerce(float), + vol.Optional(CONF_BELOW): vol.Coerce(float), + }), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW))]), +}) + def setup_filter(config): if CONF_OFFSET in config: - return OffsetFilter.new(config[CONF_OFFSET]) - if CONF_MULTIPLY in config: - return MultiplyFilter.new(config[CONF_MULTIPLY]) - if CONF_FILTER_OUT in config: - return FilterOutValueFilter.new(config[CONF_FILTER_OUT]) - if CONF_FILTER_NAN in config: - return FilterOutNANFilter() - if CONF_SLIDING_WINDOW_MOVING_AVERAGE in config: + yield OffsetFilter.new(config[CONF_OFFSET]) + elif CONF_MULTIPLY in config: + yield MultiplyFilter.new(config[CONF_MULTIPLY]) + elif CONF_FILTER_OUT in config: + yield FilterOutValueFilter.new(config[CONF_FILTER_OUT]) + elif CONF_FILTER_NAN in config: + yield FilterOutNANFilter() + elif CONF_SLIDING_WINDOW_MOVING_AVERAGE in config: conf = config[CONF_SLIDING_WINDOW_MOVING_AVERAGE] - return SlidingWindowMovingAverageFilter.new(conf[CONF_WINDOW_SIZE], conf[CONF_SEND_EVERY]) - if CONF_EXPONENTIAL_MOVING_AVERAGE in config: + yield SlidingWindowMovingAverageFilter.new(conf[CONF_WINDOW_SIZE], conf[CONF_SEND_EVERY]) + elif CONF_EXPONENTIAL_MOVING_AVERAGE in config: conf = config[CONF_EXPONENTIAL_MOVING_AVERAGE] - return ExponentialMovingAverageFilter.new(conf[CONF_ALPHA], conf[CONF_SEND_EVERY]) - if CONF_LAMBDA in config: - return LambdaFilter.new(process_lambda(config[CONF_LAMBDA], [(float_, 'x')])) - if CONF_THROTTLE in config: - return ThrottleFilter.new(config[CONF_THROTTLE]) - if CONF_DELTA in config: - return DeltaFilter.new(config[CONF_DELTA]) - if CONF_OR in config: - return OrFilter.new(setup_filters(config[CONF_OR])) - if CONF_HEARTBEAT in config: - return App.register_component(HeartbeatFilter.new(config[CONF_HEARTBEAT])) - if CONF_DEBOUNCE in config: - return App.register_component(DebounceFilter.new(config[CONF_DEBOUNCE])) - if CONF_UNIQUE in config: - return UniqueFilter.new() - raise ValueError(u"Filter unsupported: {}".format(config)) + yield ExponentialMovingAverageFilter.new(conf[CONF_ALPHA], conf[CONF_SEND_EVERY]) + elif CONF_LAMBDA in config: + lambda_ = None + for lambda_ in process_lambda(config[CONF_LAMBDA], [(float_, 'x')]): + yield None + yield LambdaFilter.new(lambda_) + elif CONF_THROTTLE in config: + yield ThrottleFilter.new(config[CONF_THROTTLE]) + elif CONF_DELTA in config: + yield DeltaFilter.new(config[CONF_DELTA]) + elif CONF_OR in config: + yield OrFilter.new(setup_filters(config[CONF_OR])) + elif CONF_HEARTBEAT in config: + yield App.register_component(HeartbeatFilter.new(config[CONF_HEARTBEAT])) + elif CONF_DEBOUNCE in config: + yield App.register_component(DebounceFilter.new(config[CONF_DEBOUNCE])) + elif CONF_UNIQUE in config: + yield UniqueFilter.new() def setup_filters(config): - return ArrayInitializer(*[setup_filter(x) for x in config]) + filters = [] + for conf in config: + filter = None + for filter in setup_filter(conf): + yield + filters.append(filter) + yield ArrayInitializer(*filters) def setup_sensor_core_(sensor_var, mqtt_var, config): @@ -131,24 +144,36 @@ def setup_sensor_core_(sensor_var, mqtt_var, config): if CONF_ACCURACY_DECIMALS in config: add(sensor_var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS])) if CONF_FILTERS in config: - add(sensor_var.set_filters(setup_filters(config[CONF_FILTERS]))) + filters = None + for filters in setup_filters(config[CONF_FILTERS]): + yield + add(sensor_var.set_filters(filters)) for conf in config.get(CONF_ON_VALUE, []): rhs = sensor_var.make_value_trigger() - trigger = Pvariable(SensorValueTrigger, conf[CONF_TRIGGER_ID], rhs) - automation.build_automation(trigger, float_, conf) + trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) + for _ in automation.build_automation(trigger, float_, conf): + yield for conf in config.get(CONF_ON_RAW_VALUE, []): rhs = sensor_var.make_raw_value_trigger() - trigger = Pvariable(RawSensorValueTrigger, conf[CONF_TRIGGER_ID], rhs) - automation.build_automation(trigger, float_, conf) + trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) + for _ in automation.build_automation(trigger, float_, conf): + yield for conf in config.get(CONF_ON_VALUE_RANGE, []): rhs = sensor_var.make_value_range_trigger() - trigger = Pvariable(ValueRangeTrigger, conf[CONF_TRIGGER_ID], rhs) + trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) if CONF_ABOVE in conf: - trigger.set_min(templatable(conf[CONF_ABOVE], float_, float_)) + template_ = None + for template_ in templatable(conf[CONF_ABOVE], float_, float_): + yield + trigger.set_min(template_) if CONF_BELOW in conf: - trigger.set_max(templatable(conf[CONF_BELOW], float_, float_)) - automation.build_automation(trigger, float_, conf) + template_ = None + for template_ in templatable(conf[CONF_BELOW], float_, float_): + yield + trigger.set_max(template_) + for _ in automation.build_automation(trigger, float_, conf): + yield if CONF_EXPIRE_AFTER in config: if config[CONF_EXPIRE_AFTER] is None: @@ -159,18 +184,18 @@ def setup_sensor_core_(sensor_var, mqtt_var, config): def setup_sensor(sensor_obj, mqtt_obj, config): - sensor_var = Pvariable(Sensor, config[CONF_ID], sensor_obj, has_side_effects=False) - mqtt_var = Pvariable(MQTTSensorComponent, config[CONF_MQTT_ID], mqtt_obj, - has_side_effects=False) - setup_sensor_core_(sensor_var, mqtt_var, config) + sensor_var = Pvariable(config[CONF_ID], sensor_obj, has_side_effects=False) + mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) + for _ in setup_sensor_core_(sensor_var, mqtt_var, config): + yield def register_sensor(var, config): - sensor_var = Pvariable(Sensor, config[CONF_ID], var, has_side_effects=True) + sensor_var = Pvariable(config[CONF_ID], var, has_side_effects=True) rhs = App.register_sensor(sensor_var) - mqtt_var = Pvariable(MQTTSensorComponent, config[CONF_MQTT_ID], rhs, - has_side_effects=True) - setup_sensor_core_(sensor_var, mqtt_var, config) + mqtt_var = Pvariable(config[CONF_MQTT_ID], rhs, has_side_effects=True) + for _ in setup_sensor_core_(sensor_var, mqtt_var, config): + yield BUILD_FLAGS = '-DUSE_SENSOR' diff --git a/esphomeyaml/components/sensor/adc.py b/esphomeyaml/components/sensor/adc.py index 6dcee54a6..70a9f8343 100644 --- a/esphomeyaml/components/sensor/adc.py +++ b/esphomeyaml/components/sensor/adc.py @@ -22,15 +22,15 @@ def validate_adc_pin(value): return pins.analog_pin(value) +MakeADCSensor = Application.MakeADCSensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('adc', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeADCSensor), vol.Required(CONF_PIN): validate_adc_pin, vol.Optional(CONF_ATTENUATION): vol.All(cv.only_on_esp32, cv.one_of(*ATTENUATION_MODES)), vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }).extend(sensor.SENSOR_SCHEMA.schema) -MakeADCSensor = Application.MakeADCSensor - def to_code(config): pin = config[CONF_PIN] @@ -38,11 +38,12 @@ def to_code(config): pin = 0 rhs = App.make_adc_sensor(config[CONF_NAME], pin, config.get(CONF_UPDATE_INTERVAL)) - make = variable(MakeADCSensor, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) adc = make.Padc if CONF_ATTENUATION in config: add(adc.set_attenuation(ATTENUATION_MODES[config[CONF_ATTENUATION]])) - sensor.setup_sensor(make.Padc, make.Pmqtt, config) + for _ in sensor.setup_sensor(make.Padc, make.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_ADC_SENSOR' diff --git a/esphomeyaml/components/sensor/ads1115.py b/esphomeyaml/components/sensor/ads1115.py index 2608c4030..eee600248 100644 --- a/esphomeyaml/components/sensor/ads1115.py +++ b/esphomeyaml/components/sensor/ads1115.py @@ -46,21 +46,23 @@ def validate_mux(value): PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('ads1115_sensor'): cv.register_variable_id, vol.Required(CONF_MULTIPLEXER): validate_mux, vol.Required(CONF_GAIN): validate_gain, - vol.Optional(CONF_ADS1115_ID): cv.variable_id, + cv.GenerateID(CONF_ADS1115_ID): cv.use_variable_id(ADS1115Component), vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }).extend(sensor.SENSOR_SCHEMA.schema) def to_code(config): - hub = get_variable(config.get(CONF_ADS1115_ID), ADS1115Component) + hub = None + for hub in get_variable(config[CONF_ADS1115_ID]): + yield mux = MUX[config[CONF_MULTIPLEXER]] gain = GAIN[config[CONF_GAIN]] rhs = hub.get_sensor(config[CONF_NAME], mux, gain, config.get(CONF_UPDATE_INTERVAL)) - sensor.register_sensor(rhs, config) + for _ in sensor.register_sensor(rhs, config): + yield BUILD_FLAGS = '-DUSE_ADS1115_SENSOR' diff --git a/esphomeyaml/components/sensor/bh1750.py b/esphomeyaml/components/sensor/bh1750.py index d119ebdbe..a9cf8f61a 100644 --- a/esphomeyaml/components/sensor/bh1750.py +++ b/esphomeyaml/components/sensor/bh1750.py @@ -14,24 +14,25 @@ BH1750_RESOLUTIONS = { 0.5: sensor.sensor_ns.BH1750_RESOLUTION_0P5_LX, } +MakeBH1750Sensor = Application.MakeBH1750Sensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('bh1750_sensor', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBH1750Sensor), vol.Optional(CONF_ADDRESS, default=0x23): cv.i2c_address, vol.Optional(CONF_RESOLUTION): vol.All(cv.positive_float, cv.one_of(*BH1750_RESOLUTIONS)), vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }).extend(sensor.SENSOR_SCHEMA.schema) -MakeBH1750Sensor = Application.MakeBH1750Sensor - def to_code(config): rhs = App.make_bh1750_sensor(config[CONF_NAME], config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL)) - make_bh1750 = variable(MakeBH1750Sensor, config[CONF_MAKE_ID], rhs) + make_bh1750 = variable(config[CONF_MAKE_ID], rhs) bh1750 = make_bh1750.Pbh1750 if CONF_RESOLUTION in config: add(bh1750.set_resolution(BH1750_RESOLUTIONS[config[CONF_RESOLUTION]])) - sensor.setup_sensor(bh1750, make_bh1750.Pmqtt, config) + for _ in sensor.setup_sensor(bh1750, make_bh1750.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_BH1750' diff --git a/esphomeyaml/components/sensor/bme280.py b/esphomeyaml/components/sensor/bme280.py index 3f264aaf2..7634ad342 100644 --- a/esphomeyaml/components/sensor/bme280.py +++ b/esphomeyaml/components/sensor/bme280.py @@ -29,8 +29,10 @@ BME280_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({ vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, cv.one_of(*OVERSAMPLING_OPTIONS)), }) +MakeBME280Sensor = Application.MakeBME280Sensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('bme280', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBME280Sensor), vol.Optional(CONF_ADDRESS, default=0x77): cv.i2c_address, vol.Required(CONF_TEMPERATURE): BME280_OVERSAMPLING_SENSOR_SCHEMA, vol.Required(CONF_PRESSURE): BME280_OVERSAMPLING_SENSOR_SCHEMA, @@ -39,8 +41,6 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }) -MakeBME280Sensor = Application.MakeBME280Sensor - def to_code(config): rhs = App.make_bme280_sensor(config[CONF_TEMPERATURE][CONF_NAME], @@ -48,7 +48,7 @@ def to_code(config): config[CONF_HUMIDITY][CONF_NAME], config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL)) - make = variable(MakeBME280Sensor, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) bme280 = make.Pbme280 if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]: constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]] @@ -63,12 +63,15 @@ def to_code(config): constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]] add(bme280.set_iir_filter(constant)) - sensor.setup_sensor(bme280.Pget_temperature_sensor(), make.Pmqtt_temperature, - config[CONF_TEMPERATURE]) - sensor.setup_sensor(bme280.Pget_pressure_sensor(), make.Pmqtt_pressure, - config[CONF_PRESSURE]) - sensor.setup_sensor(bme280.Pget_humidity_sensor(), make.Pmqtt_humidity, - config[CONF_HUMIDITY]) + for _ in sensor.setup_sensor(bme280.Pget_temperature_sensor(), make.Pmqtt_temperature, + config[CONF_TEMPERATURE]): + yield + for _ in sensor.setup_sensor(bme280.Pget_pressure_sensor(), make.Pmqtt_pressure, + config[CONF_PRESSURE]): + yield + for _ in sensor.setup_sensor(bme280.Pget_humidity_sensor(), make.Pmqtt_humidity, + config[CONF_HUMIDITY]): + yield BUILD_FLAGS = '-DUSE_BME280' diff --git a/esphomeyaml/components/sensor/bme680.py b/esphomeyaml/components/sensor/bme680.py index d717c8a4a..773bcfda8 100644 --- a/esphomeyaml/components/sensor/bme680.py +++ b/esphomeyaml/components/sensor/bme680.py @@ -33,8 +33,10 @@ BME680_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({ vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, cv.one_of(*OVERSAMPLING_OPTIONS)), }) +MakeBME680Sensor = Application.MakeBME680Sensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('bme680', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBME680Sensor), vol.Optional(CONF_ADDRESS, default=0x76): cv.i2c_address, vol.Required(CONF_TEMPERATURE): BME680_OVERSAMPLING_SENSOR_SCHEMA, vol.Required(CONF_PRESSURE): BME680_OVERSAMPLING_SENSOR_SCHEMA, @@ -45,8 +47,6 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }) -MakeBME680Sensor = Application.MakeBME680Sensor - def to_code(config): rhs = App.make_bme680_sensor(config[CONF_TEMPERATURE][CONF_NAME], @@ -55,7 +55,7 @@ def to_code(config): config[CONF_GAS_RESISTANCE][CONF_NAME], config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL)) - make = variable(MakeBME680Sensor, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) bme680 = make.Pbme680 if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]: constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]] @@ -70,14 +70,18 @@ def to_code(config): constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]] add(bme680.set_iir_filter(constant)) - sensor.setup_sensor(bme680.Pget_temperature_sensor(), make.Pmqtt_temperature, - config[CONF_TEMPERATURE]) - sensor.setup_sensor(bme680.Pget_pressure_sensor(), make.Pmqtt_pressure, - config[CONF_PRESSURE]) - sensor.setup_sensor(bme680.Pget_humidity_sensor(), make.Pmqtt_humidity, - config[CONF_HUMIDITY]) - sensor.setup_sensor(bme680.Pget_gas_resistance_sensor(), make.Pmqtt_gas_resistance, - config[CONF_GAS_RESISTANCE]) + for _ in sensor.setup_sensor(bme680.Pget_temperature_sensor(), make.Pmqtt_temperature, + config[CONF_TEMPERATURE]): + yield + for _ in sensor.setup_sensor(bme680.Pget_pressure_sensor(), make.Pmqtt_pressure, + config[CONF_PRESSURE]): + yield + for _ in sensor.setup_sensor(bme680.Pget_humidity_sensor(), make.Pmqtt_humidity, + config[CONF_HUMIDITY]): + yield + for _ in sensor.setup_sensor(bme680.Pget_gas_resistance_sensor(), make.Pmqtt_gas_resistance, + config[CONF_GAS_RESISTANCE]): + yield BUILD_FLAGS = '-DUSE_BME680' diff --git a/esphomeyaml/components/sensor/bmp085.py b/esphomeyaml/components/sensor/bmp085.py index 4d63b6b94..0b89c8145 100644 --- a/esphomeyaml/components/sensor/bmp085.py +++ b/esphomeyaml/components/sensor/bmp085.py @@ -8,29 +8,31 @@ from esphomeyaml.helpers import App, HexIntLiteral, add, variable, Application DEPENDENCIES = ['i2c'] +MakeBMP085Sensor = Application.MakeBMP085Sensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('bmp085_sensor', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBMP085Sensor), vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA, vol.Required(CONF_PRESSURE): sensor.SENSOR_SCHEMA, vol.Optional(CONF_ADDRESS): cv.i2c_address, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }) -MakeBMP085Sensor = Application.MakeBMP085Sensor - def to_code(config): rhs = App.make_bmp085_sensor(config[CONF_TEMPERATURE][CONF_NAME], config[CONF_PRESSURE][CONF_NAME], config.get(CONF_UPDATE_INTERVAL)) - bmp = variable(MakeBMP085Sensor, config[CONF_MAKE_ID], rhs) + bmp = variable(config[CONF_MAKE_ID], rhs) if CONF_ADDRESS in config: add(bmp.Pbmp.set_address(HexIntLiteral(config[CONF_ADDRESS]))) - sensor.setup_sensor(bmp.Pbmp.Pget_temperature_sensor(), bmp.Pmqtt_temperature, - config[CONF_TEMPERATURE]) - sensor.setup_sensor(bmp.Pbmp.Pget_pressure_sensor(), bmp.Pmqtt_pressure, - config[CONF_PRESSURE]) + for _ in sensor.setup_sensor(bmp.Pbmp.Pget_temperature_sensor(), bmp.Pmqtt_temperature, + config[CONF_TEMPERATURE]): + yield + for _ in sensor.setup_sensor(bmp.Pbmp.Pget_pressure_sensor(), bmp.Pmqtt_pressure, + config[CONF_PRESSURE]): + yield BUILD_FLAGS = '-DUSE_BMP085_SENSOR' diff --git a/esphomeyaml/components/sensor/dallas.py b/esphomeyaml/components/sensor/dallas.py index d770ee6ec..6a5097b57 100644 --- a/esphomeyaml/components/sensor/dallas.py +++ b/esphomeyaml/components/sensor/dallas.py @@ -10,13 +10,15 @@ from esphomeyaml.helpers import HexIntLiteral, get_variable PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({ vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int, vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int, - vol.Optional(CONF_DALLAS_ID): cv.variable_id, + cv.GenerateID(CONF_DALLAS_ID): cv.use_variable_id(DallasComponent), vol.Optional(CONF_RESOLUTION): vol.All(vol.Coerce(int), vol.Range(min=8, max=12)), }).extend(sensor.SENSOR_SCHEMA.schema), cv.has_at_least_one_key(CONF_ADDRESS, CONF_INDEX)) def to_code(config): - hub = get_variable(config.get(CONF_DALLAS_ID), DallasComponent) + hub = None + for hub in get_variable(config[CONF_DALLAS_ID]): + yield update_interval = config.get(CONF_UPDATE_INTERVAL) if CONF_RESOLUTION in config and update_interval is None: update_interval = 10000 @@ -28,7 +30,8 @@ def to_code(config): else: rhs = hub.Pget_sensor_by_index(config[CONF_NAME], config[CONF_INDEX], update_interval, config.get(CONF_RESOLUTION)) - sensor.register_sensor(rhs, config) + for _ in sensor.register_sensor(rhs, config): + yield BUILD_FLAGS = '-DUSE_DALLAS_SENSOR' diff --git a/esphomeyaml/components/sensor/dht.py b/esphomeyaml/components/sensor/dht.py index 0b3b28f62..ba7d29b95 100644 --- a/esphomeyaml/components/sensor/dht.py +++ b/esphomeyaml/components/sensor/dht.py @@ -15,8 +15,10 @@ DHT_MODELS = { 'RHT03': sensor.sensor_ns.DHT_MODEL_RHT03, } +MakeDHTSensor = Application.MakeDHTSensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('dht_sensor', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeDHTSensor), vol.Required(CONF_PIN): GPIO_OUTPUT_PIN_SCHEMA, vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA, @@ -24,23 +26,25 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }) -MakeDHTSensor = Application.MakeDHTSensor - def to_code(config): - pin = gpio_output_pin_expression(config[CONF_PIN]) + pin = None + for pin in gpio_output_pin_expression(config[CONF_PIN]): + yield rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME], pin, config.get(CONF_UPDATE_INTERVAL)) - dht = variable(MakeDHTSensor, config[CONF_MAKE_ID], rhs) + dht = variable(config[CONF_MAKE_ID], rhs) if CONF_MODEL in config: constant = DHT_MODELS[config[CONF_MODEL]] add(dht.Pdht.set_dht_model(constant)) - sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), - dht.Pmqtt_temperature, config[CONF_TEMPERATURE]) - sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(), - dht.Pmqtt_humidity, config[CONF_HUMIDITY]) + for _ in sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), + dht.Pmqtt_temperature, config[CONF_TEMPERATURE]): + yield + for _ in sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(), + dht.Pmqtt_humidity, config[CONF_HUMIDITY]): + yield BUILD_FLAGS = '-DUSE_DHT_SENSOR' diff --git a/esphomeyaml/components/sensor/dht12.py b/esphomeyaml/components/sensor/dht12.py index c74a6f73a..88105a076 100644 --- a/esphomeyaml/components/sensor/dht12.py +++ b/esphomeyaml/components/sensor/dht12.py @@ -8,26 +8,28 @@ from esphomeyaml.helpers import App, Application, variable DEPENDENCIES = ['i2c'] +MakeDHT12Sensor = Application.MakeDHT12Sensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('dht_sensor', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeDHT12Sensor), vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }) -MakeDHT12Sensor = Application.MakeDHT12Sensor - def to_code(config): rhs = App.make_dht12_sensor(config[CONF_TEMPERATURE][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME], config.get(CONF_UPDATE_INTERVAL)) - dht = variable(MakeDHT12Sensor, config[CONF_MAKE_ID], rhs) + dht = variable(config[CONF_MAKE_ID], rhs) - sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), dht.Pmqtt_temperature, - config[CONF_TEMPERATURE]) - sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(), dht.Pmqtt_humidity, - config[CONF_HUMIDITY]) + for _ in sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), dht.Pmqtt_temperature, + config[CONF_TEMPERATURE]): + yield + for _ in sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(), dht.Pmqtt_humidity, + config[CONF_HUMIDITY]): + yield BUILD_FLAGS = '-DUSE_DHT12_SENSOR' diff --git a/esphomeyaml/components/sensor/hdc1080.py b/esphomeyaml/components/sensor/hdc1080.py index 94a9dd6d1..d295345ef 100644 --- a/esphomeyaml/components/sensor/hdc1080.py +++ b/esphomeyaml/components/sensor/hdc1080.py @@ -8,26 +8,29 @@ from esphomeyaml.helpers import App, variable, Application DEPENDENCIES = ['i2c'] +MakeHDC1080Sensor = Application.MakeHDC1080Sensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('hdc1080_sensor', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeHDC1080Sensor), vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }) -MakeHDC1080Sensor = Application.MakeHDC1080Sensor - def to_code(config): rhs = App.make_hdc1080_sensor(config[CONF_TEMPERATURE][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME], config.get(CONF_UPDATE_INTERVAL)) - hdc1080 = variable(MakeHDC1080Sensor, config[CONF_MAKE_ID], rhs) + hdc1080 = variable(config[CONF_MAKE_ID], rhs) - sensor.setup_sensor(hdc1080.Phdc1080.Pget_temperature_sensor(), hdc1080.Pmqtt_temperature, - config[CONF_TEMPERATURE]) - sensor.setup_sensor(hdc1080.Phdc1080.Pget_humidity_sensor(), hdc1080.Pmqtt_humidity, - config[CONF_HUMIDITY]) + for _ in sensor.setup_sensor(hdc1080.Phdc1080.Pget_temperature_sensor(), + hdc1080.Pmqtt_temperature, + config[CONF_TEMPERATURE]): + yield + for _ in sensor.setup_sensor(hdc1080.Phdc1080.Pget_humidity_sensor(), hdc1080.Pmqtt_humidity, + config[CONF_HUMIDITY]): + yield BUILD_FLAGS = '-DUSE_HDC1080_SENSOR' diff --git a/esphomeyaml/components/sensor/htu21d.py b/esphomeyaml/components/sensor/htu21d.py index fb8a49a80..ef85bc781 100644 --- a/esphomeyaml/components/sensor/htu21d.py +++ b/esphomeyaml/components/sensor/htu21d.py @@ -8,25 +8,27 @@ from esphomeyaml.helpers import App, variable, Application DEPENDENCIES = ['i2c'] +MakeHTU21DSensor = Application.MakeHTU21DSensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('htu21d', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeHTU21DSensor), vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }) -MakeHTU21DSensor = Application.MakeHTU21DSensor - def to_code(config): rhs = App.make_htu21d_sensor(config[CONF_TEMPERATURE][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME], config.get(CONF_UPDATE_INTERVAL)) - htu21d = variable(MakeHTU21DSensor, config[CONF_MAKE_ID], rhs) - sensor.setup_sensor(htu21d.Phtu21d.Pget_temperature_sensor(), htu21d.Pmqtt_temperature, - config[CONF_TEMPERATURE]) - sensor.setup_sensor(htu21d.Phtu21d.Pget_humidity_sensor(), htu21d.Pmqtt_humidity, - config[CONF_HUMIDITY]) + htu21d = variable(config[CONF_MAKE_ID], rhs) + for _ in sensor.setup_sensor(htu21d.Phtu21d.Pget_temperature_sensor(), htu21d.Pmqtt_temperature, + config[CONF_TEMPERATURE]): + yield + for _ in sensor.setup_sensor(htu21d.Phtu21d.Pget_humidity_sensor(), htu21d.Pmqtt_humidity, + config[CONF_HUMIDITY]): + yield BUILD_FLAGS = '-DUSE_HTU21D_SENSOR' diff --git a/esphomeyaml/components/sensor/max6675.py b/esphomeyaml/components/sensor/max6675.py index de0d3e937..12af4f90c 100644 --- a/esphomeyaml/components/sensor/max6675.py +++ b/esphomeyaml/components/sensor/max6675.py @@ -8,25 +8,32 @@ from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN_CLOCK, CONF_PIN_ from esphomeyaml.helpers import App, Application, gpio_input_pin_expression, \ gpio_output_pin_expression, variable +MakeMAX6675Sensor = Application.MakeMAX6675Sensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('max6675', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeMAX6675Sensor), vol.Required(CONF_PIN_CS): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Required(CONF_PIN_CLOCK): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Optional(CONF_PIN_MISO): pins.GPIO_INPUT_PIN_SCHEMA, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }).extend(sensor.SENSOR_SCHEMA.schema) -MakeMAX6675Sensor = Application.MakeMAX6675Sensor - def to_code(config): - pin_cs = gpio_output_pin_expression(config[CONF_PIN_CS]) - pin_clock = gpio_output_pin_expression(config[CONF_PIN_CLOCK]) - pin_miso = gpio_input_pin_expression(config[CONF_PIN_MISO]) + pin_cs = None + for pin_cs in gpio_output_pin_expression(config[CONF_PIN_CS]): + yield + pin_clock = None + for pin_clock in gpio_output_pin_expression(config[CONF_PIN_CLOCK]): + yield + pin_miso = None + for pin_miso in gpio_input_pin_expression(config[CONF_PIN_MISO]): + yield rhs = App.make_max6675_sensor(config[CONF_NAME], pin_cs, pin_clock, pin_miso, config.get(CONF_UPDATE_INTERVAL)) - make = variable(MakeMAX6675Sensor, config[CONF_MAKE_ID], rhs) - sensor.setup_sensor(make.Pmax6675, make.Pmqtt, config) + make = variable(config[CONF_MAKE_ID], rhs) + for _ in sensor.setup_sensor(make.Pmax6675, make.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_MAX6675_SENSOR' diff --git a/esphomeyaml/components/sensor/mpu6050.py b/esphomeyaml/components/sensor/mpu6050.py index 0d7ee1659..f4cae29b1 100644 --- a/esphomeyaml/components/sensor/mpu6050.py +++ b/esphomeyaml/components/sensor/mpu6050.py @@ -2,8 +2,7 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor -from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_MQTT_ID, CONF_NAME, \ - CONF_TEMPERATURE, \ +from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \ CONF_UPDATE_INTERVAL from esphomeyaml.helpers import App, Pvariable @@ -16,8 +15,13 @@ CONF_GYRO_X = 'gyro_x' CONF_GYRO_Y = 'gyro_y' CONF_GYRO_Z = 'gyro_z' +MPU6050Component = sensor.sensor_ns.MPU6050Component +MPU6050AccelSensor = sensor.sensor_ns.MPU6050AccelSensor +MPU6050GyroSensor = sensor.sensor_ns.MPU6050GyroSensor +MPU6050TemperatureSensor = sensor.sensor_ns.MPU6050TemperatureSensor + PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('mpu6050', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(MPU6050Component), vol.Optional(CONF_ADDRESS, default=0x68): cv.i2c_address, vol.Optional(CONF_ACCEL_X): sensor.SENSOR_SCHEMA, vol.Optional(CONF_ACCEL_Y): sensor.SENSOR_SCHEMA, @@ -30,50 +34,45 @@ PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({ }), cv.has_at_least_one_key(CONF_ACCEL_X, CONF_ACCEL_Y, CONF_ACCEL_Z, CONF_GYRO_X, CONF_GYRO_Y, CONF_GYRO_Z)) -MPU6050Component = sensor.sensor_ns.MPU6050Component -MPU6050AccelSensor = sensor.sensor_ns.MPU6050AccelSensor -MPU6050GyroSensor = sensor.sensor_ns.MPU6050GyroSensor -MPU6050TemperatureSensor = sensor.sensor_ns.MPU6050TemperatureSensor - def to_code(config): rhs = App.make_mpu6050_sensor(config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL)) - mpu = Pvariable(MPU6050Component, config[CONF_MAKE_ID], rhs) + mpu = Pvariable(config[CONF_ID], rhs) if CONF_ACCEL_X in config: conf = config[CONF_ACCEL_X] rhs = mpu.Pmake_accel_x_sensor(conf[CONF_NAME]) - sensor_ = Pvariable(MPU6050AccelSensor, conf[CONF_MQTT_ID], rhs) - sensor.register_sensor(sensor_, conf) + for _ in sensor.register_sensor(rhs, conf): + yield if CONF_ACCEL_Y in config: conf = config[CONF_ACCEL_Y] rhs = mpu.Pmake_accel_y_sensor(conf[CONF_NAME]) - sensor_ = Pvariable(MPU6050AccelSensor, conf[CONF_MQTT_ID], rhs) - sensor.register_sensor(sensor_, conf) + for _ in sensor.register_sensor(rhs, conf): + yield if CONF_ACCEL_Z in config: conf = config[CONF_ACCEL_Z] rhs = mpu.Pmake_accel_z_sensor(conf[CONF_NAME]) - sensor_ = Pvariable(MPU6050AccelSensor, conf[CONF_MQTT_ID], rhs) - sensor.register_sensor(sensor_, conf) + for _ in sensor.register_sensor(rhs, conf): + yield if CONF_GYRO_X in config: conf = config[CONF_GYRO_X] rhs = mpu.Pmake_gyro_x_sensor(conf[CONF_NAME]) - sensor_ = Pvariable(MPU6050GyroSensor, conf[CONF_MQTT_ID], rhs) - sensor.register_sensor(sensor_, conf) + for _ in sensor.register_sensor(rhs, conf): + yield if CONF_GYRO_Y in config: conf = config[CONF_GYRO_Y] rhs = mpu.Pmake_gyro_y_sensor(conf[CONF_NAME]) - sensor_ = Pvariable(MPU6050GyroSensor, conf[CONF_MQTT_ID], rhs) - sensor.register_sensor(sensor_, conf) + for _ in sensor.register_sensor(rhs, conf): + yield if CONF_GYRO_Z in config: conf = config[CONF_GYRO_Z] rhs = mpu.Pmake_gyro_z_sensor(conf[CONF_NAME]) - sensor_ = Pvariable(MPU6050GyroSensor, conf[CONF_MQTT_ID], rhs) - sensor.register_sensor(sensor_, conf) + for _ in sensor.register_sensor(rhs, conf): + yield if CONF_TEMPERATURE in config: conf = config[CONF_TEMPERATURE] rhs = mpu.Pmake_temperature_sensor(conf[CONF_NAME]) - sensor_ = Pvariable(MPU6050TemperatureSensor, conf[CONF_MQTT_ID], rhs) - sensor.register_sensor(sensor_, conf) + for _ in sensor.register_sensor(rhs, conf): + yield BUILD_FLAGS = '-DUSE_MPU6050' diff --git a/esphomeyaml/components/sensor/pulse_counter.py b/esphomeyaml/components/sensor/pulse_counter.py index c4e2020f0..2ee0109bc 100644 --- a/esphomeyaml/components/sensor/pulse_counter.py +++ b/esphomeyaml/components/sensor/pulse_counter.py @@ -27,8 +27,10 @@ COUNT_MODES = { COUNT_MODE_SCHEMA = vol.All(vol.Upper, cv.one_of(*COUNT_MODES)) +MakePulseCounterSensor = Application.MakePulseCounterSensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('pulse_counter', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakePulseCounterSensor), vol.Required(CONF_PIN): pins.input_pin, vol.Optional(CONF_PULL_MODE): GPIO_PULL_MODE_SCHEMA, vol.Optional(CONF_COUNT_MODE): vol.Schema({ @@ -39,13 +41,11 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }).extend(sensor.SENSOR_SCHEMA.schema) -MakePulseCounterSensor = Application.MakePulseCounterSensor - def to_code(config): rhs = App.make_pulse_counter_sensor(config[CONF_NAME], config[CONF_PIN], config.get(CONF_UPDATE_INTERVAL)) - make = variable(MakePulseCounterSensor, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) pcnt = make.Ppcnt if CONF_PULL_MODE in config: pull_mode = GPIO_PULL_MODES[config[CONF_PULL_MODE]] @@ -57,7 +57,8 @@ def to_code(config): add(pcnt.set_edge_mode(rising_edge, falling_edge)) if CONF_INTERNAL_FILTER in config: add(pcnt.set_filter(config[CONF_INTERNAL_FILTER])) - sensor.setup_sensor(make.Ppcnt, make.Pmqtt, config) + for _ in sensor.setup_sensor(make.Ppcnt, make.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_PULSE_COUNTER_SENSOR' diff --git a/esphomeyaml/components/sensor/rotary_encoder.py b/esphomeyaml/components/sensor/rotary_encoder.py index dbdef902e..f4f02d833 100644 --- a/esphomeyaml/components/sensor/rotary_encoder.py +++ b/esphomeyaml/components/sensor/rotary_encoder.py @@ -16,30 +16,37 @@ CONF_PIN_A = 'pin_a' CONF_PIN_B = 'pin_b' CONF_PIN_RESET = 'pin_reset' +MakeRotaryEncoderSensor = Application.MakeRotaryEncoderSensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('rotary_encoder', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeRotaryEncoderSensor), vol.Required(CONF_PIN_A): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA, vol.Required(CONF_PIN_B): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA, vol.Optional(CONF_PIN_RESET): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA, vol.Optional(CONF_RESOLUTION): vol.All(cv.string, cv.one_of(*RESOLUTIONS)), }).extend(sensor.SENSOR_SCHEMA.schema) -MakeRotaryEncoderSensor = Application.MakeRotaryEncoderSensor - def to_code(config): - pin_a = gpio_input_pin_expression(config[CONF_PIN_A]) - pin_b = gpio_input_pin_expression(config[CONF_PIN_B]) + pin_a = None + for pin_a in gpio_input_pin_expression(config[CONF_PIN_A]): + yield + pin_b = None + for pin_b in gpio_input_pin_expression(config[CONF_PIN_B]): + yield rhs = App.make_rotary_encoder_sensor(config[CONF_NAME], pin_a, pin_b) - make = variable(MakeRotaryEncoderSensor, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) encoder = make.Protary_encoder if CONF_PIN_RESET in config: - pin_i = gpio_input_pin_expression(config[CONF_PIN_RESET]) + pin_i = None + for pin_i in gpio_input_pin_expression(config[CONF_PIN_RESET]): + yield add(encoder.set_reset_pin(pin_i)) if CONF_RESOLUTION in config: resolution = RESOLUTIONS[config[CONF_RESOLUTION]] add(encoder.set_resolution(resolution)) - sensor.setup_sensor(encoder, make.Pmqtt, config) + for _ in sensor.setup_sensor(encoder, make.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_ROTARY_ENCODER_SENSOR' diff --git a/esphomeyaml/components/sensor/sht3xd.py b/esphomeyaml/components/sensor/sht3xd.py index 3c87770dd..bda732daf 100644 --- a/esphomeyaml/components/sensor/sht3xd.py +++ b/esphomeyaml/components/sensor/sht3xd.py @@ -14,8 +14,10 @@ SHT_ACCURACIES = { 'HIGH': sensor.sensor_ns.SHT3XD_ACCURACY_HIGH, } +MakeSHT3XDSensor = Application.MakeSHT3XDSensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('sht3xd', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeSHT3XDSensor), vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA, vol.Optional(CONF_ADDRESS, default=0x44): cv.i2c_address, @@ -23,22 +25,22 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }) -MakeSHT3XDSensor = Application.MakeSHT3XDSensor - def to_code(config): rhs = App.make_sht3xd_sensor(config[CONF_TEMPERATURE][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME], config.get(CONF_UPDATE_INTERVAL)) - sht3xd = variable(MakeSHT3XDSensor, config[CONF_MAKE_ID], rhs) + sht3xd = variable(config[CONF_MAKE_ID], rhs) if CONF_ACCURACY in config: add(sht3xd.Psht3xd.set_accuracy(SHT_ACCURACIES[config[CONF_ACCURACY]])) - sensor.setup_sensor(sht3xd.Psht3xd.Pget_temperature_sensor(), sht3xd.Pmqtt_temperature, - config[CONF_TEMPERATURE]) - sensor.setup_sensor(sht3xd.Psht3xd.Pget_humidity_sensor(), sht3xd.Pmqtt_humidity, - config[CONF_HUMIDITY]) + for _ in sensor.setup_sensor(sht3xd.Psht3xd.Pget_temperature_sensor(), sht3xd.Pmqtt_temperature, + config[CONF_TEMPERATURE]): + yield + for _ in sensor.setup_sensor(sht3xd.Psht3xd.Pget_humidity_sensor(), sht3xd.Pmqtt_humidity, + config[CONF_HUMIDITY]): + yield BUILD_FLAGS = '-DUSE_SHT3XD' diff --git a/esphomeyaml/components/sensor/template.py b/esphomeyaml/components/sensor/template.py index 6fd20d96c..0df453603 100644 --- a/esphomeyaml/components/sensor/template.py +++ b/esphomeyaml/components/sensor/template.py @@ -5,21 +5,24 @@ from esphomeyaml.components import sensor from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL from esphomeyaml.helpers import App, process_lambda, variable, Application +MakeTemplateSensor = Application.MakeTemplateSensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('template_sensor', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeTemplateSensor), vol.Required(CONF_LAMBDA): cv.lambda_, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }).extend(sensor.SENSOR_SCHEMA.schema) -MakeTemplateSensor = Application.MakeTemplateSensor - def to_code(config): - template_ = process_lambda(config[CONF_LAMBDA], []) + template_ = None + for template_ in process_lambda(config[CONF_LAMBDA], []): + yield rhs = App.make_template_sensor(config[CONF_NAME], template_, config.get(CONF_UPDATE_INTERVAL)) - make = variable(MakeTemplateSensor, config[CONF_MAKE_ID], rhs) - sensor.setup_sensor(make.Ptemplate_, make.Pmqtt, config) + make = variable(config[CONF_MAKE_ID], rhs) + for _ in sensor.setup_sensor(make.Ptemplate_, make.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_TEMPLATE_SENSOR' diff --git a/esphomeyaml/components/sensor/tsl2561.py b/esphomeyaml/components/sensor/tsl2561.py index 72c880476..2b8c91a29 100644 --- a/esphomeyaml/components/sensor/tsl2561.py +++ b/esphomeyaml/components/sensor/tsl2561.py @@ -28,8 +28,10 @@ def validate_integration_time(value): return value +MakeTSL2561Sensor = Application.MakeTSL2561Sensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('tsl2561_sensor', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeTSL2561Sensor), vol.Optional(CONF_ADDRESS, default=0x39): cv.i2c_address, vol.Optional(CONF_INTEGRATION_TIME): validate_integration_time, vol.Optional(CONF_GAIN): vol.All(vol.Upper, cv.one_of(*GAINS)), @@ -37,13 +39,11 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }).extend(sensor.SENSOR_SCHEMA.schema) -MakeTSL2561Sensor = Application.MakeTSL2561Sensor - def to_code(config): rhs = App.make_tsl2561_sensor(config[CONF_NAME], config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL)) - make_tsl = variable(MakeTSL2561Sensor, config[CONF_MAKE_ID], rhs) + make_tsl = variable(config[CONF_MAKE_ID], rhs) tsl2561 = make_tsl.Ptsl2561 if CONF_INTEGRATION_TIME in config: add(tsl2561.set_integration_time(INTEGRATION_TIMES[config[CONF_INTEGRATION_TIME]])) @@ -51,7 +51,8 @@ def to_code(config): add(tsl2561.set_gain(GAINS[config[CONF_GAIN]])) if CONF_IS_CS_PACKAGE in config: add(tsl2561.set_is_cs_package(config[CONF_IS_CS_PACKAGE])) - sensor.setup_sensor(tsl2561, make_tsl.Pmqtt, config) + for _ in sensor.setup_sensor(tsl2561, make_tsl.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_TSL2561' diff --git a/esphomeyaml/components/sensor/ultrasonic.py b/esphomeyaml/components/sensor/ultrasonic.py index 2cde3af02..f413b7566 100644 --- a/esphomeyaml/components/sensor/ultrasonic.py +++ b/esphomeyaml/components/sensor/ultrasonic.py @@ -8,8 +8,10 @@ from esphomeyaml.const import CONF_ECHO_PIN, CONF_MAKE_ID, CONF_NAME, CONF_TIMEO from esphomeyaml.helpers import App, Application, add, gpio_input_pin_expression, \ gpio_output_pin_expression, variable +MakeUltrasonicSensor = Application.MakeUltrasonicSensor + PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ - cv.GenerateID('ultrasonic', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeUltrasonicSensor), vol.Required(CONF_TRIGGER_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Required(CONF_ECHO_PIN): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA, vol.Exclusive(CONF_TIMEOUT_METER, 'timeout'): cv.positive_float, @@ -17,21 +19,24 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, }).extend(sensor.SENSOR_SCHEMA.schema) -MakeUltrasonicSensor = Application.MakeUltrasonicSensor - def to_code(config): - trigger = gpio_output_pin_expression(config[CONF_TRIGGER_PIN]) - echo = gpio_input_pin_expression(config[CONF_ECHO_PIN]) + trigger = None + for trigger in gpio_output_pin_expression(config[CONF_TRIGGER_PIN]): + yield + echo = None + for trigger in gpio_input_pin_expression(config[CONF_ECHO_PIN]): + yield rhs = App.make_ultrasonic_sensor(config[CONF_NAME], trigger, echo, config.get(CONF_UPDATE_INTERVAL)) - make = variable(MakeUltrasonicSensor, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) ultrasonic = make.Pultrasonic if CONF_TIMEOUT_TIME in config: add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT_TIME])) elif CONF_TIMEOUT_METER in config: add(ultrasonic.set_timeout_m(config[CONF_TIMEOUT_METER])) - sensor.setup_sensor(ultrasonic, make.Pmqtt, config) + for _ in sensor.setup_sensor(ultrasonic, make.Pmqtt, config): + yield BUILD_FLAGS = '-DUSE_ULTRASONIC_SENSOR' diff --git a/esphomeyaml/components/switch/__init__.py b/esphomeyaml/components/switch/__init__.py index 04871c324..554d14738 100644 --- a/esphomeyaml/components/switch/__init__.py +++ b/esphomeyaml/components/switch/__init__.py @@ -8,13 +8,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ }) -SWITCH_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ - cv.GenerateID('switch_'): cv.register_variable_id, - cv.GenerateID('mqtt_switch', CONF_MQTT_ID): cv.register_variable_id, - vol.Optional(CONF_ICON): cv.icon, - vol.Optional(CONF_INVERTED): cv.boolean, -}) - switch_ns = esphomelib_ns.namespace('switch_') Switch = switch_ns.Switch MQTTSwitchComponent = switch_ns.MQTTSwitchComponent @@ -22,6 +15,13 @@ ToggleAction = switch_ns.ToggleAction TurnOffAction = switch_ns.TurnOffAction TurnOnAction = switch_ns.TurnOnAction +SWITCH_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(Switch), + cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTSwitchComponent), + vol.Optional(CONF_ICON): cv.icon, + vol.Optional(CONF_INVERTED): cv.boolean, +}) + def setup_switch_core_(switch_var, mqtt_var, config): if CONF_ICON in config: @@ -33,17 +33,15 @@ def setup_switch_core_(switch_var, mqtt_var, config): def setup_switch(switch_obj, mqtt_obj, config): - switch_var = Pvariable(Switch, config[CONF_ID], switch_obj, has_side_effects=False) - mqtt_var = Pvariable(MQTTSwitchComponent, config[CONF_MQTT_ID], mqtt_obj, - has_side_effects=False) + switch_var = Pvariable(config[CONF_ID], switch_obj, has_side_effects=False) + mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) setup_switch_core_(switch_var, mqtt_var, config) def register_switch(var, config): - switch_var = Pvariable(Switch, config[CONF_ID], var, has_side_effects=True) + switch_var = Pvariable(config[CONF_ID], var, has_side_effects=True) rhs = App.register_switch(switch_var) - mqtt_var = Pvariable(MQTTSwitchComponent, config[CONF_MQTT_ID], rhs, - has_side_effects=True) + mqtt_var = Pvariable(config[CONF_MQTT_ID], rhs, has_side_effects=True) setup_switch_core_(switch_var, mqtt_var, config) diff --git a/esphomeyaml/components/switch/gpio.py b/esphomeyaml/components/switch/gpio.py index 11cee6387..e54b792e9 100644 --- a/esphomeyaml/components/switch/gpio.py +++ b/esphomeyaml/components/switch/gpio.py @@ -6,17 +6,20 @@ from esphomeyaml.components import switch from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN from esphomeyaml.helpers import App, Application, gpio_output_pin_expression, variable +MakeGPIOSwitch = Application.MakeGPIOSwitch + PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ - cv.GenerateID('gpio_switch', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeGPIOSwitch), vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, }).extend(switch.SWITCH_SCHEMA.schema) -MakeGPIOSwitch = Application.MakeGPIOSwitch - def to_code(config): - rhs = App.make_gpio_switch(config[CONF_NAME], gpio_output_pin_expression(config[CONF_PIN])) - gpio = variable(MakeGPIOSwitch, config[CONF_MAKE_ID], rhs) + pin = None + for pin in gpio_output_pin_expression(config[CONF_PIN]): + yield + rhs = App.make_gpio_switch(config[CONF_NAME], pin) + gpio = variable(config[CONF_MAKE_ID], rhs) switch.setup_switch(gpio.Pswitch_, gpio.Pmqtt, config) diff --git a/esphomeyaml/components/switch/ir_transmitter.py b/esphomeyaml/components/switch/ir_transmitter.py index 0dd6144a5..0a9ba4109 100644 --- a/esphomeyaml/components/switch/ir_transmitter.py +++ b/esphomeyaml/components/switch/ir_transmitter.py @@ -17,7 +17,6 @@ WAIT_TIME_MESSAGE = "The wait_time_us option has been renamed to wait_time in or "ambiguity. " PLATFORM_SCHEMA = vol.All(switch.PLATFORM_SCHEMA.extend({ - cv.GenerateID('ir_transmitter_switch'): cv.register_variable_id, vol.Exclusive(CONF_NEC, 'code'): vol.Schema({ vol.Required(CONF_ADDRESS): cv.hex_uint16_t, vol.Required(CONF_COMMAND): cv.hex_uint16_t, @@ -44,7 +43,7 @@ PLATFORM_SCHEMA = vol.All(switch.PLATFORM_SCHEMA.extend({ vol.Optional('wait_time_us'): cv.invalid(WAIT_TIME_MESSAGE), })), - vol.Optional(CONF_IR_TRANSMITTER_ID): cv.variable_id, + cv.GenerateID(CONF_IR_TRANSMITTER_ID): cv.use_variable_id(IRTransmitterComponent), vol.Optional(CONF_INVERTED): cv.invalid("IR Transmitters do not support inverted mode!"), }).extend(switch.SWITCH_SCHEMA.schema), cv.has_at_least_one_key(*IR_KEYS)) @@ -94,7 +93,9 @@ def exp_send_data(config): def to_code(config): - ir = get_variable(config.get(CONF_IR_TRANSMITTER_ID), IRTransmitterComponent) + ir = None + for ir in get_variable(config[CONF_IR_TRANSMITTER_ID]): + yield send_data = exp_send_data(config) rhs = App.register_component(ir.create_transmitter(config[CONF_NAME], send_data)) switch.register_switch(rhs, config) diff --git a/esphomeyaml/components/switch/output.py b/esphomeyaml/components/switch/output.py index c4e4785b0..d67649745 100644 --- a/esphomeyaml/components/switch/output.py +++ b/esphomeyaml/components/switch/output.py @@ -5,18 +5,20 @@ from esphomeyaml.components import switch from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT from esphomeyaml.helpers import App, Application, get_variable, variable -PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ - cv.GenerateID('output_switch', CONF_MAKE_ID): cv.register_variable_id, - vol.Required(CONF_OUTPUT): cv.variable_id, -}).extend(switch.SWITCH_SCHEMA.schema) - MakeSimpleSwitch = Application.MakeSimpleSwitch +PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeSimpleSwitch), + vol.Required(CONF_OUTPUT): cv.use_variable_id(None), +}).extend(switch.SWITCH_SCHEMA.schema) + def to_code(config): - output = get_variable(config[CONF_OUTPUT]) + output = None + for output in get_variable(config[CONF_OUTPUT]): + yield rhs = App.make_simple_switch(config[CONF_NAME], output) - gpio = variable(MakeSimpleSwitch, config[CONF_MAKE_ID], rhs) + gpio = variable(config[CONF_MAKE_ID], rhs) switch.setup_switch(gpio.Pswitch_, gpio.Pmqtt, config) diff --git a/esphomeyaml/components/switch/restart.py b/esphomeyaml/components/switch/restart.py index fd97face6..e28a60130 100644 --- a/esphomeyaml/components/switch/restart.py +++ b/esphomeyaml/components/switch/restart.py @@ -5,17 +5,17 @@ from esphomeyaml.components import switch from esphomeyaml.const import CONF_INVERTED, CONF_MAKE_ID, CONF_NAME from esphomeyaml.helpers import App, Application, variable +MakeRestartSwitch = Application.MakeRestartSwitch + PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ - cv.GenerateID('restart_switch', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeRestartSwitch), vol.Optional(CONF_INVERTED): cv.invalid("Restart switches do not support inverted mode!"), }).extend(switch.SWITCH_SCHEMA.schema) -MakeRestartSwitch = Application.MakeRestartSwitch - def to_code(config): rhs = App.make_restart_switch(config[CONF_NAME]) - restart = variable(MakeRestartSwitch, config[CONF_MAKE_ID], rhs) + restart = variable(config[CONF_MAKE_ID], rhs) switch.setup_switch(restart.Prestart, restart.Pmqtt, config) diff --git a/esphomeyaml/components/switch/shutdown.py b/esphomeyaml/components/switch/shutdown.py index 46517c3b2..8e8d98fbf 100644 --- a/esphomeyaml/components/switch/shutdown.py +++ b/esphomeyaml/components/switch/shutdown.py @@ -5,17 +5,17 @@ from esphomeyaml.components import switch from esphomeyaml.const import CONF_INVERTED, CONF_MAKE_ID, CONF_NAME from esphomeyaml.helpers import App, Application, variable +MakeShutdownSwitch = Application.MakeShutdownSwitch + PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ - cv.GenerateID('shutdown_switch', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeShutdownSwitch), vol.Optional(CONF_INVERTED): cv.invalid("Shutdown switches do not support inverted mode!"), }).extend(switch.SWITCH_SCHEMA.schema) -MakeShutdownSwitch = Application.MakeShutdownSwitch - def to_code(config): rhs = App.make_shutdown_switch(config[CONF_NAME]) - shutdown = variable(MakeShutdownSwitch, config[CONF_MAKE_ID], rhs) + shutdown = variable(config[CONF_MAKE_ID], rhs) switch.setup_switch(shutdown.Pshutdown, shutdown.Pmqtt, config) diff --git a/esphomeyaml/components/switch/template.py b/esphomeyaml/components/switch/template.py index 9286b528d..1aed25db0 100644 --- a/esphomeyaml/components/switch/template.py +++ b/esphomeyaml/components/switch/template.py @@ -7,29 +7,35 @@ from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_TURN_OF CONF_TURN_ON_ACTION, CONF_OPTIMISTIC from esphomeyaml.helpers import App, Application, process_lambda, variable, NoArg, add +MakeTemplateSwitch = Application.MakeTemplateSwitch + PLATFORM_SCHEMA = vol.All(switch.PLATFORM_SCHEMA.extend({ - cv.GenerateID('template_switch', CONF_MAKE_ID): cv.register_variable_id, + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeTemplateSwitch), vol.Optional(CONF_LAMBDA): cv.lambda_, vol.Optional(CONF_OPTIMISTIC): cv.boolean, vol.Optional(CONF_TURN_OFF_ACTION): automation.ACTIONS_SCHEMA, vol.Optional(CONF_TURN_ON_ACTION): automation.ACTIONS_SCHEMA, }).extend(switch.SWITCH_SCHEMA.schema), cv.has_at_least_one_key(CONF_LAMBDA, CONF_OPTIMISTIC)) -MakeTemplateSwitch = Application.MakeTemplateSwitch - def to_code(config): rhs = App.make_template_switch(config[CONF_NAME]) - make = variable(MakeTemplateSwitch, config[CONF_MAKE_ID], rhs) + make = variable(config[CONF_MAKE_ID], rhs) if CONF_LAMBDA in config: - template_ = process_lambda(config[CONF_LAMBDA], []) + template_ = None + for template_ in process_lambda(config[CONF_LAMBDA], []): + yield add(make.Ptemplate_.set_state_lambda(template_)) if CONF_TURN_OFF_ACTION in config: - actions = automation.build_actions(config[CONF_TURN_OFF_ACTION], NoArg) + actions = None + for actions in automation.build_actions(config[CONF_TURN_OFF_ACTION], NoArg): + yield add(make.Ptemplate_.add_turn_off_actions(actions)) if CONF_TURN_ON_ACTION in config: - actions = automation.build_actions(config[CONF_TURN_ON_ACTION], NoArg) + actions = None + for actions in automation.build_actions(config[CONF_TURN_ON_ACTION], NoArg): + yield add(make.Ptemplate_.add_turn_on_actions(actions)) if CONF_OPTIMISTIC in config: add(make.Ptemplate_.set_optimistic(config[CONF_OPTIMISTIC])) diff --git a/esphomeyaml/components/web_server.py b/esphomeyaml/components/web_server.py index 9a6eaef39..8092cec4a 100644 --- a/esphomeyaml/components/web_server.py +++ b/esphomeyaml/components/web_server.py @@ -9,19 +9,19 @@ from esphomeyaml.helpers import App, add, Pvariable, esphomelib_ns _LOGGER = logging.getLogger(__name__) +WebServer = esphomelib_ns.WebServer + CONFIG_SCHEMA = vol.Schema({ - cv.GenerateID('web_server'): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(WebServer), vol.Optional(CONF_PORT): cv.port, vol.Optional(CONF_CSS_URL): vol.Url, vol.Optional(CONF_JS_URL): vol.Url, }) -WebServer = esphomelib_ns.WebServer - def to_code(config): rhs = App.init_web_server(config.get(CONF_PORT)) - web_server = Pvariable(WebServer, config[CONF_ID], rhs) + web_server = Pvariable(config[CONF_ID], rhs) if CONF_CSS_URL in config: add(web_server.set_css_url(config[CONF_CSS_URL])) if CONF_JS_URL in config: diff --git a/esphomeyaml/components/wifi.py b/esphomeyaml/components/wifi.py index d10af8269..dc1e96b14 100644 --- a/esphomeyaml/components/wifi.py +++ b/esphomeyaml/components/wifi.py @@ -30,8 +30,13 @@ STA_MANUAL_IP_SCHEMA = AP_MANUAL_IP_SCHEMA.extend({ vol.Inclusive(CONF_DNS2, 'dns'): cv.ipv4, }) +# pylint: disable=invalid-name +IPAddress = global_ns.IPAddress +ManualIP = esphomelib_ns.ManualIP +WiFiComponent = esphomelib_ns.WiFiComponent + CONFIG_SCHEMA = vol.Schema({ - cv.GenerateID('wifi'): cv.register_variable_id, + cv.GenerateID(): cv.declare_variable_id(WiFiComponent), vol.Optional(CONF_SSID): cv.ssid, vol.Optional(CONF_PASSWORD): validate_password, vol.Optional(CONF_MANUAL_IP): STA_MANUAL_IP_SCHEMA, @@ -45,11 +50,6 @@ CONFIG_SCHEMA = vol.Schema({ vol.Required(CONF_DOMAIN, default='.local'): cv.domainname, }) -# pylint: disable=invalid-name -IPAddress = global_ns.IPAddress -ManualIP = esphomelib_ns.ManualIP -WiFiComponent = esphomelib_ns.WiFiComponent - def safe_ip(ip): if ip is None: @@ -75,7 +75,7 @@ def to_code(config): rhs = App.init_wifi(config[CONF_SSID], config.get(CONF_PASSWORD)) else: rhs = App.init_wifi() - wifi = Pvariable(WiFiComponent, config[CONF_ID], rhs) + wifi = Pvariable(config[CONF_ID], rhs) if sta and CONF_MANUAL_IP in config: add(wifi.set_sta_manual_ip(manual_ip(config[CONF_MANUAL_IP]))) diff --git a/esphomeyaml/config.py b/esphomeyaml/config.py index cce08cc32..a6c66abb0 100644 --- a/esphomeyaml/config.py +++ b/esphomeyaml/config.py @@ -93,6 +93,50 @@ class Config(OrderedDict): self.errors.append((message, domain, config)) +def iter_ids(config, prefix=None, parent=None): + prefix = prefix or [] + parent = parent or {} + if isinstance(config, core.ID): + yield config, prefix, parent + elif isinstance(config, core.Lambda): + for id in config.requires_ids: + yield id, prefix, parent + elif isinstance(config, list): + for i, item in enumerate(config): + for result in iter_ids(item, prefix + [str(i)], config): + yield result + elif isinstance(config, dict): + for key, value in config.iteritems(): + for result in iter_ids(value, prefix + [str(key)], config): + yield result + + +def do_id_pass(result): + declare_ids = [] + searching_ids = [] + for id, prefix, config in iter_ids(result): + if id.is_declaration: + if id.id is not None and any(v[0].id == id.id for v in declare_ids): + result.add_error("ID {} redefined!".format(id.id), '.'.join(prefix), config) + continue + declare_ids.append((id, prefix, config)) + else: + searching_ids.append((id, prefix, config)) + # Resolve default ids after manual IDs + for id, _, _ in declare_ids: + id.resolve([v[0].id for v in declare_ids]) + + # Check searched IDs + for id, prefix, config in searching_ids: + if id.id is not None and not any(v[0].id == id.id for v in declare_ids): + result.add_error("Couldn't find ID {}".format(id.id), '.'.join(prefix), config) + if id.id is None and id.type is not None: + id.id = next((v[0].id for v in declare_ids if v[0].type == id.type), None) + if id.id is None: + result.add_error("Couldn't resolve ID for type {}".format(id.type), + '.'.join(prefix), config) + + def validate_config(config): global _ALL_COMPONENTS @@ -185,6 +229,8 @@ def validate_config(config): continue platforms.append(p_validated) result[domain] = platforms + + do_id_pass(result) return result @@ -237,8 +283,10 @@ def load_config(path): try: result = validate_config(config) + except ESPHomeYAMLError: + raise except Exception: - print(u"Unexpected exception while reading configuration:") + _LOGGER.error(u"Unexpected exception while reading configuration:") raise return result @@ -279,18 +327,18 @@ def dump_dict(layer, indent_count=3, listi=False, **kwargs): def read_config(path): - _LOGGER.debug("Reading configuration...") + _LOGGER.info("Reading configuration...") try: res = load_config(path) except ESPHomeYAMLError as err: _LOGGER.error(u"Error while reading config: %s", err) return None excepts = {} - for err in res.errors: - domain = err[1] or u"General Error" - excepts.setdefault(domain, []).append(err[0]) - if err[2] is not None: - excepts[domain].append(err[2]) + for message, domain, config in res.errors: + domain = domain or u"General Error" + excepts.setdefault(domain, []).append(message) + if config is not None: + excepts[domain].append(config) if excepts: print(color('bold_white', u"Failed config")) diff --git a/esphomeyaml/config_validation.py b/esphomeyaml/config_validation.py index 6e2fd2276..a3e00fd89 100644 --- a/esphomeyaml/config_validation.py +++ b/esphomeyaml/config_validation.py @@ -12,9 +12,8 @@ from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOV CONF_NAME, CONF_PAYLOAD_AVAILABLE, \ CONF_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC, \ ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 -from esphomeyaml.core import HexInt, IPAddress, TimePeriod, TimePeriodMicroseconds, \ - TimePeriodMilliseconds, TimePeriodSeconds, Lambda -from esphomeyaml.helpers import ensure_unique_string +from esphomeyaml.core import HexInt, IPAddress, Lambda, TimePeriod, TimePeriodMicroseconds, \ + TimePeriodMilliseconds, TimePeriodSeconds _LOGGER = logging.getLogger(__name__) @@ -136,7 +135,7 @@ def int_(value): hex_int = vol.Coerce(hex_int_) -def variable_id(value): +def variable_id_str_(value): value = string(value) if not value: raise vol.Invalid("ID must not be empty") @@ -153,11 +152,32 @@ def variable_id(value): return value +def use_variable_id(type): + def validator(value): + if value is None: + return core.ID(None, is_declaration=False, type=type) + + return core.ID(variable_id_str_(value), is_declaration=False, type=type) + + return validator + + +def declare_variable_id(type): + def validator(value): + if value is None: + return core.ID(None, is_declaration=True, type=type) + + return core.ID(variable_id_str_(value), is_declaration=True, type=type) + + return validator + + def templatable(other_validators): def validator(value): if isinstance(value, Lambda): return value return other_validators(value) + return validator @@ -224,7 +244,6 @@ time_period_dict = vol.All( 'seconds', 'milliseconds', 'microseconds'), lambda value: TimePeriod(**value)) - TIME_PERIOD_EXPLICIT_MESSAGE = ("The old way of being able to write time values without a " "time unit (like \"1000\" for 1000 milliseconds) has been " "removed in 1.5.0 as it was ambiguous in some places. Please " @@ -322,7 +341,6 @@ positive_time_period_microseconds = vol.All(positive_time_period, time_period_in positive_not_null_time_period = vol.All(time_period, vol.Range(min=TimePeriod(), min_included=False)) - METRIC_SUFFIXES = { 'E': 1e18, 'P': 1e15, 'T': 1e12, 'G': 1e9, 'M': 1e6, 'k': 1e3, 'da': 10, 'd': 1e-1, 'c': 1e-2, 'm': 0.001, u'ยต': 1e-6, 'u': 1e-6, 'n': 1e-9, 'p': 1e-12, 'f': 1e-15, 'a': 1e-18, @@ -479,6 +497,7 @@ def percentage(value): def invalid(message): def validator(value): raise vol.Invalid(message) + return validator @@ -493,6 +512,7 @@ def one_of(*values): if value not in values: raise vol.Invalid(u"Unknown value '{}', must be one of {}".format(value, options)) return value + return validator @@ -505,26 +525,10 @@ def lambda_(value): REGISTERED_IDS = set() -def register_variable_id(value): - s = variable_id(value) - if s in REGISTERED_IDS: - raise vol.Invalid("This ID has already been used") - REGISTERED_IDS.add(s) - return s - - class GenerateID(vol.Optional): - def __init__(self, basename, key=CONF_ID): - self._basename = basename - super(GenerateID, self).__init__(key, default=self.default_variable_id) + def __init__(self, key=CONF_ID): + super(GenerateID, self).__init__(key, default=lambda: None) - def default_variable_id(self): - return ensure_unique_string(self._basename, REGISTERED_IDS) - - -REQUIRED_ID_SCHEMA = vol.Schema({ - vol.Required(CONF_ID): register_variable_id, -}) PLATFORM_SCHEMA = vol.Schema({ vol.Required(CONF_PLATFORM): valid, diff --git a/esphomeyaml/const.py b/esphomeyaml/const.py index fc454f18f..2d5f9eac7 100644 --- a/esphomeyaml/const.py +++ b/esphomeyaml/const.py @@ -253,3 +253,5 @@ ESP_BOARDS_FOR_PLATFORM = { ESP_PLATFORM_ESP32: ESP32_BOARDS, ESP_PLATFORM_ESP8266: ESP8266_BOARDS } + +ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyz0123456789_' diff --git a/esphomeyaml/core.py b/esphomeyaml/core.py index fc5860237..ba0fd1a63 100644 --- a/esphomeyaml/core.py +++ b/esphomeyaml/core.py @@ -1,4 +1,5 @@ import math +import re from collections import OrderedDict @@ -174,11 +175,59 @@ class TimePeriodSeconds(TimePeriod): class Lambda(object): def __init__(self, value): self.value = value + self.parts = re.split(r'id\(\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\)\.', value) + self.requires_ids = [ID(self.parts[i]) for i in range(1, len(self.parts), 2)] def __str__(self): + return self.value + + def __repr__(self): return u'Lambda<{}>'.format(self.value) +def ensure_unique_string(preferred_string, current_strings): + test_string = preferred_string + current_strings_set = set(current_strings) + + tries = 1 + + while test_string in current_strings_set: + tries += 1 + test_string = u"{}_{}".format(preferred_string, tries) + + return test_string + + +class ID(object): + def __init__(self, id, is_declaration=False, type=None): + self.id = id + self.is_manual = id is not None + self.is_declaration = is_declaration + self.type = type + + def resolve(self, registered_ids): + if self.id is None: + base = str(self.type).replace('::', '_').lower() + name = ''.join(c for c in base if c.isalnum() or c == '_') + self.id = ensure_unique_string(name, registered_ids) + return self.id + + def __str__(self): + return self.id + + def __repr__(self): + return u'ID<{} declaration={}, type={}, manual={}>'.format( + self.id, self.is_declaration, self.type, self.is_manual) + + def __eq__(self, other): + if not isinstance(other, ID): + raise ValueError("other must be ID") + return self.id == other.id + + def __hash__(self): + return hash(self.id) + + CONFIG_PATH = None SIMPLIFY = True ESP_PLATFORM = '' diff --git a/esphomeyaml/dashboard/dashboard.py b/esphomeyaml/dashboard/dashboard.py index 5427f3d69..e92323943 100644 --- a/esphomeyaml/dashboard/dashboard.py +++ b/esphomeyaml/dashboard/dashboard.py @@ -8,7 +8,10 @@ import os import random import subprocess -_LOGGER = logging.getLogger(__name__) +from esphomeyaml.core import ESPHomeYAMLError +from esphomeyaml import const, core, __main__ +from esphomeyaml.__main__ import get_serial_ports, get_base_path, get_name +from esphomeyaml.helpers import quote try: import tornado @@ -20,13 +23,9 @@ try: import tornado.websocket import tornado.concurrent except ImportError as err: - _LOGGER.error("Attempted to load dashboard, but tornado is not installed! " - "Please run \"pip2 install tornado esptool\" in your terminal.") - -from esphomeyaml import const, core, __main__ -from esphomeyaml.__main__ import get_serial_ports, get_base_path, get_name -from esphomeyaml.helpers import quote + tornado = None +_LOGGER = logging.getLogger(__name__) CONFIG_DIR = '' @@ -167,6 +166,11 @@ def make_app(): def start_web_server(args): global CONFIG_DIR + + if tornado is None: + raise ESPHomeYAMLError("Attempted to load dashboard, but tornado is not installed! " + "Please run \"pip2 install tornado esptool\" in your terminal.") + CONFIG_DIR = args.configuration if not os.path.exists(CONFIG_DIR): os.makedirs(CONFIG_DIR) diff --git a/esphomeyaml/helpers.py b/esphomeyaml/helpers.py index 84e99d5d8..444b04995 100644 --- a/esphomeyaml/helpers.py +++ b/esphomeyaml/helpers.py @@ -1,16 +1,17 @@ from __future__ import print_function +import inspect import logging import re -from collections import OrderedDict, deque +from collections import OrderedDict from esphomeyaml import core from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, \ CONF_INVERTED, \ CONF_MODE, CONF_NUMBER, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_PCF8574, \ CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC -from esphomeyaml.core import ESPHomeYAMLError, HexInt, TimePeriodMicroseconds, \ - TimePeriodMilliseconds, TimePeriodSeconds, Lambda +from esphomeyaml.core import ESPHomeYAMLError, HexInt, Lambda, TimePeriodMicroseconds, \ + TimePeriodMilliseconds, TimePeriodSeconds _LOGGER = logging.getLogger(__name__) @@ -356,81 +357,108 @@ def statement(expression): return ExpressionStatement(expression) -def register_variable(type, id, obj): - _VARIABLES[id] = obj, type +def register_variable(id, obj): + _LOGGER.debug("Registered variable %s of type %s", id.id, id.type) + _VARIABLES[id] = obj # pylint: disable=redefined-builtin, invalid-name -def variable(type, id, rhs): +def variable(id, rhs, type=None): rhs = safe_exp(rhs) obj = MockObj(id, u'.') - assignment = AssignmentExpression(type, '', id, rhs, obj) + id.type = type or id.type + assignment = AssignmentExpression(id.type, '', id, rhs, obj) add(assignment) - register_variable(type, id, obj) + register_variable(id, obj) obj.requires.append(assignment) return obj -def Pvariable(type, id, rhs, has_side_effects=True): +def Pvariable(id, rhs, has_side_effects=True, type=None): rhs = safe_exp(rhs) if not has_side_effects and hasattr(rhs, '_has_side_effects'): # pylint: disable=attribute-defined-outside-init, protected-access rhs._has_side_effects = False obj = MockObj(id, u'->', has_side_effects=has_side_effects) - assignment = AssignmentExpression(type, '*', id, rhs, obj) + id.type = type or id.type + assignment = AssignmentExpression(id.type, '*', id, rhs, obj) add(assignment) - register_variable(type, id, obj) + register_variable(id, obj) obj.requires.append(assignment) return obj -_QUEUE = deque() +_TASKS = [] _VARIABLES = {} _EXPRESSIONS = [] -def get_variable(id, type=None): - def get_result(): - if id is not None: - if id in _VARIABLES: - return _VARIABLES[id][0] - elif type is not None: - return next((x[0] for x in _VARIABLES.itervalues() if x[1] == type), None) - return None - - while _QUEUE: - result = get_result() - if result is not None: - return result - func, config = _QUEUE.popleft() - func(config) - if id is None and type is None: - return None - result = get_result() - if result is None: - if type is None: - raise ESPHomeYAMLError(u"Couldn't find ID '{}'".format(id)) - raise ESPHomeYAMLError(u"Couldn't find ID '{}' with type '{}'".format(id, type)) - return result +def get_variable(id): + while True: + if id in _VARIABLES: + yield _VARIABLES[id] + return + _LOGGER.debug("Waiting for variable %s", id) + yield None def process_lambda(value, parameters, capture='=', return_type=None): if value is None: - return None - parts = re.split(r'id\(\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\)\.', value.value) + yield + return + parts = value.parts[:] for i in range(1, len(parts), 2): - parts[i] = get_variable(parts[i])._ - return LambdaExpression(parts, parameters, capture, return_type) + var = None + for var in get_variable(parts[i]): + yield + parts[i] = var._ + yield LambdaExpression(parts, parameters, capture, return_type) + return def templatable(value, input_type, output_type): if isinstance(value, Lambda): - return process_lambda(value, [(input_type, 'x')], return_type=output_type) - return value + lambda_ = None + for lambda_ in process_lambda(value, [(input_type, 'x')], return_type=output_type): + yield None + yield lambda_ + else: + yield value -def add_task(func, config): - _QUEUE.append((func, config)) +def add_task(func, config, domain): + if inspect.isgeneratorfunction(func): + def func_(): + yield + for _ in func(config): + yield + else: + def func_(): + yield + func(config) + _TASKS.append((func_(), domain)) + + +def run_tasks(): + global _TASKS + + new_tasks = [] + for task, domain in _TASKS: + try: + task.next() + new_tasks.append((task, domain)) + except StopIteration: + pass + _TASKS = new_tasks + + +def flush_tasks(): + for _ in range(1000000): + run_tasks() + if not _TASKS: + break + else: + raise ESPHomeYAMLError("Circular dependency detected!") def add(expression, require=True): @@ -528,32 +556,43 @@ def get_gpio_pin_number(conf): def generic_gpio_pin_expression_(conf, mock_obj, default_mode): if conf is None: - return None + return number = conf[CONF_NUMBER] inverted = conf.get(CONF_INVERTED) if CONF_PCF8574 in conf: - hub = get_variable(conf[CONF_PCF8574], 'io::PCF8574Component') + hub = None + for hub in get_variable(conf[CONF_PCF8574]): + yield None if default_mode == u'INPUT': mode = conf.get(CONF_MODE, u'INPUT') - return hub.make_input_pin(number, - RawExpression('PCF8574_' + mode), - inverted) + yield hub.make_input_pin(number, + RawExpression('PCF8574_' + mode), + inverted) + return elif default_mode == u'OUTPUT': - return hub.make_output_pin(number, inverted) + yield hub.make_output_pin(number, inverted) + return else: raise ESPHomeYAMLError(u"Unknown default mode {}".format(default_mode)) if len(conf) == 1: - return IntLiteral(number) + yield IntLiteral(number) + return mode = RawExpression(conf.get(CONF_MODE, default_mode)) - return mock_obj(number, mode, inverted) + yield mock_obj(number, mode, inverted) def gpio_output_pin_expression(conf): - return generic_gpio_pin_expression_(conf, GPIOOutputPin, 'OUTPUT') + exp = None + for exp in generic_gpio_pin_expression_(conf, GPIOOutputPin, 'OUTPUT'): + yield None + yield exp def gpio_input_pin_expression(conf): - return generic_gpio_pin_expression_(conf, GPIOInputPin, 'INPUT') + exp = None + for exp in generic_gpio_pin_expression_(conf, GPIOInputPin, 'INPUT'): + yield None + yield exp def setup_mqtt_component(obj, config): diff --git a/esphomeyaml/pins.py b/esphomeyaml/pins.py index 5709fa6b6..f94aa512a 100644 --- a/esphomeyaml/pins.py +++ b/esphomeyaml/pins.py @@ -4,6 +4,7 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml import core +from esphomeyaml.components import pcf8574 from esphomeyaml.const import CONF_INVERTED, CONF_MODE, CONF_NUMBER, CONF_PCF8574, \ ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 @@ -202,7 +203,7 @@ def shorthand_input_pin(value): PCF8574_OUTPUT_PIN_SCHEMA = vol.Schema({ - vol.Required(CONF_PCF8574): cv.variable_id, + vol.Required(CONF_PCF8574): cv.use_variable_id(pcf8574.PCF8574Component), vol.Required(CONF_NUMBER): vol.Coerce(int), vol.Optional(CONF_MODE): vol.All(vol.Upper, "OUTPUT"), vol.Optional(CONF_INVERTED, default=False): cv.boolean, diff --git a/esphomeyaml/yaml_util.py b/esphomeyaml/yaml_util.py index 0707565bf..a18bd7ce9 100644 --- a/esphomeyaml/yaml_util.py +++ b/esphomeyaml/yaml_util.py @@ -8,6 +8,7 @@ from collections import OrderedDict import yaml +from esphomeyaml import core from esphomeyaml.core import ESPHomeYAMLError, HexInt, IPAddress, Lambda, MACAddress, TimePeriod _LOGGER = logging.getLogger(__name__) @@ -279,6 +280,10 @@ def represent_lambda(_, data): return node +def represent_id(_, data): + return yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=data.id) + + yaml.SafeDumper.add_representer( OrderedDict, lambda dumper, value: @@ -297,3 +302,4 @@ yaml.SafeDumper.add_representer(IPAddress, stringify_representer) yaml.SafeDumper.add_representer(MACAddress, stringify_representer) yaml.SafeDumper.add_multi_representer(TimePeriod, represent_time_period) yaml.SafeDumper.add_multi_representer(Lambda, represent_lambda) +yaml.SafeDumper.add_multi_representer(core.ID, represent_id) diff --git a/pylintrc b/pylintrc index 24b0b0408..a3cb5bce3 100644 --- a/pylintrc +++ b/pylintrc @@ -16,6 +16,7 @@ disable= duplicate-code, invalid-name, cyclic-import, + redefined-builtin, additional-builtins=