From 17ec2bb905e1a0c427dcffcb135ff7f7fa5925d9 Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Mon, 19 Nov 2018 22:12:24 +0100 Subject: [PATCH] Update --- esphomeyaml/__main__.py | 64 +- esphomeyaml/automation.py | 21 +- esphomeyaml/components/ads1115.py | 6 +- .../components/binary_sensor/__init__.py | 13 +- .../components/binary_sensor/custom.py | 37 + .../binary_sensor/esp32_ble_tracker.py | 3 +- .../components/binary_sensor/esp32_touch.py | 3 +- esphomeyaml/components/binary_sensor/gpio.py | 5 +- .../components/binary_sensor/nextion.py | 3 +- esphomeyaml/components/binary_sensor/pn532.py | 2 +- .../components/binary_sensor/rdm6300.py | 2 +- .../binary_sensor/remote_receiver.py | 2 +- .../components/binary_sensor/status.py | 4 +- .../components/binary_sensor/template.py | 5 +- esphomeyaml/components/cover/__init__.py | 9 +- esphomeyaml/components/cover/template.py | 5 +- esphomeyaml/components/dallas.py | 8 +- esphomeyaml/components/debug.py | 3 +- esphomeyaml/components/deep_sleep.py | 11 +- esphomeyaml/components/display/__init__.py | 4 +- esphomeyaml/components/display/lcd_gpio.py | 7 +- esphomeyaml/components/display/lcd_pcf8574.py | 10 +- esphomeyaml/components/display/max7219.py | 7 +- esphomeyaml/components/display/nextion.py | 6 +- esphomeyaml/components/display/ssd1306_i2c.py | 11 +- esphomeyaml/components/display/ssd1306_spi.py | 12 +- .../components/display/waveshare_epaper.py | 6 +- esphomeyaml/components/esp32_ble_beacon.py | 5 +- esphomeyaml/components/esp32_ble_tracker.py | 5 +- esphomeyaml/components/esp32_touch.py | 11 +- esphomeyaml/components/fan/__init__.py | 15 +- esphomeyaml/components/fan/binary.py | 4 +- esphomeyaml/components/fan/speed.py | 3 +- esphomeyaml/components/font.py | 12 +- esphomeyaml/components/globals.py | 5 +- esphomeyaml/components/i2c.py | 14 +- esphomeyaml/components/image.py | 12 +- esphomeyaml/components/light/__init__.py | 12 +- esphomeyaml/components/light/binary.py | 4 +- esphomeyaml/components/light/cwww.py | 4 +- .../components/light/fastled_clockless.py | 13 +- esphomeyaml/components/light/fastled_spi.py | 13 +- esphomeyaml/components/light/monochromatic.py | 4 +- esphomeyaml/components/light/rgb.py | 10 +- esphomeyaml/components/light/rgbw.py | 10 +- esphomeyaml/components/light/rgbww.py | 6 +- esphomeyaml/components/logger.py | 9 +- esphomeyaml/components/mqtt.py | 52 +- esphomeyaml/components/my9231.py | 15 +- esphomeyaml/components/ota.py | 17 +- esphomeyaml/components/output/__init__.py | 14 +- esphomeyaml/components/output/custom.py | 72 ++ esphomeyaml/components/output/esp8266_pwm.py | 7 +- esphomeyaml/components/output/gpio.py | 7 +- esphomeyaml/components/output/ledc.py | 6 +- esphomeyaml/components/output/my9231.py | 5 +- esphomeyaml/components/output/pca9685.py | 4 +- esphomeyaml/components/pca9685.py | 8 +- esphomeyaml/components/pcf8574.py | 4 +- esphomeyaml/components/pn532.py | 13 +- esphomeyaml/components/power_supply.py | 7 +- esphomeyaml/components/rdm6300.py | 6 +- esphomeyaml/components/remote_receiver.py | 7 +- esphomeyaml/components/remote_transmitter.py | 5 +- esphomeyaml/components/script.py | 4 +- esphomeyaml/components/sensor/__init__.py | 14 +- esphomeyaml/components/sensor/adc.py | 12 +- esphomeyaml/components/sensor/ads1115.py | 5 +- esphomeyaml/components/sensor/bh1750.py | 6 +- esphomeyaml/components/sensor/ble_rssi.py | 5 +- esphomeyaml/components/sensor/bme280.py | 4 +- esphomeyaml/components/sensor/bme680.py | 4 +- esphomeyaml/components/sensor/bmp085.py | 4 +- esphomeyaml/components/sensor/bmp280.py | 6 +- esphomeyaml/components/sensor/cse7766.py | 4 +- esphomeyaml/components/sensor/custom.py | 3 +- esphomeyaml/components/sensor/dallas.py | 4 +- esphomeyaml/components/sensor/dht.py | 15 +- esphomeyaml/components/sensor/dht12.py | 11 +- esphomeyaml/components/sensor/duty_cycle.py | 7 +- esphomeyaml/components/sensor/esp32_hall.py | 4 +- .../components/sensor/esp32_temperature.py | 34 + esphomeyaml/components/sensor/hdc1080.py | 5 +- esphomeyaml/components/sensor/hlw8012.py | 5 +- esphomeyaml/components/sensor/hmc5883l.py | 4 +- esphomeyaml/components/sensor/htu21d.py | 5 +- esphomeyaml/components/sensor/hx711.py | 9 +- esphomeyaml/components/sensor/ina219.py | 4 +- esphomeyaml/components/sensor/ina3221.py | 4 +- esphomeyaml/components/sensor/max6675.py | 7 +- esphomeyaml/components/sensor/mhz19.py | 5 +- esphomeyaml/components/sensor/mpu6050.py | 4 +- .../components/sensor/mqtt_subscribe.py | 4 +- esphomeyaml/components/sensor/ms5611.py | 6 +- esphomeyaml/components/sensor/pmsx003.py | 5 +- .../components/sensor/pulse_counter.py | 15 +- .../components/sensor/rotary_encoder.py | 7 +- esphomeyaml/components/sensor/sht3xd.py | 9 +- esphomeyaml/components/sensor/tcs34725.py | 4 +- esphomeyaml/components/sensor/template.py | 7 +- .../components/sensor/total_daily_energy.py | 4 +- esphomeyaml/components/sensor/tsl2561.py | 6 +- esphomeyaml/components/sensor/ultrasonic.py | 6 +- esphomeyaml/components/sensor/uptime.py | 6 +- esphomeyaml/components/sensor/wifi_signal.py | 6 +- .../components/sensor/xiaomi_miflora.py | 2 +- esphomeyaml/components/sensor/xiaomi_mijia.py | 2 +- esphomeyaml/components/spi.py | 8 +- esphomeyaml/components/status_led.py | 5 +- esphomeyaml/components/stepper/__init__.py | 7 +- esphomeyaml/components/stepper/a4988.py | 5 +- esphomeyaml/components/switch/__init__.py | 6 +- esphomeyaml/components/switch/custom.py | 36 + esphomeyaml/components/switch/gpio.py | 5 +- esphomeyaml/components/switch/output.py | 4 +- .../components/switch/remote_transmitter.py | 2 +- esphomeyaml/components/switch/restart.py | 5 +- esphomeyaml/components/switch/shutdown.py | 3 +- esphomeyaml/components/switch/template.py | 11 +- esphomeyaml/components/switch/uart.py | 5 +- .../components/text_sensor/__init__.py | 11 +- esphomeyaml/components/text_sensor/custom.py | 36 + .../components/text_sensor/mqtt_subscribe.py | 4 +- .../components/text_sensor/template.py | 5 +- esphomeyaml/components/text_sensor/version.py | 4 +- esphomeyaml/components/time/__init__.py | 7 +- esphomeyaml/components/time/sntp.py | 4 +- esphomeyaml/components/uart.py | 6 +- esphomeyaml/components/web_server.py | 11 +- esphomeyaml/components/wifi.py | 12 +- esphomeyaml/config.py | 37 +- esphomeyaml/config_validation.py | 16 +- esphomeyaml/const.py | 7 +- esphomeyaml/core.py | 184 ++++- esphomeyaml/core_config.py | 104 +-- esphomeyaml/cpp_generator.py | 535 ++++++++++++++ esphomeyaml/cpp_helpers.py | 49 ++ esphomeyaml/cpp_types.py | 35 + esphomeyaml/dashboard/dashboard.py | 203 ++++- esphomeyaml/dashboard/templates/index.html | 129 +++- esphomeyaml/espota2.py | 49 +- esphomeyaml/helpers.py | 698 +----------------- esphomeyaml/mqtt.py | 10 +- esphomeyaml/pins.py | 100 +-- esphomeyaml/platformio_api.py | 6 +- esphomeyaml/storage_json.py | 127 ++++ esphomeyaml/wizard.py | 23 +- esphomeyaml/writer.py | 319 +++++--- esphomeyaml/yaml_util.py | 18 +- requirements.txt | 1 + setup.py | 1 + 151 files changed, 2402 insertions(+), 1427 deletions(-) create mode 100644 esphomeyaml/components/binary_sensor/custom.py create mode 100644 esphomeyaml/components/output/custom.py create mode 100644 esphomeyaml/components/sensor/esp32_temperature.py create mode 100644 esphomeyaml/components/switch/custom.py create mode 100644 esphomeyaml/components/text_sensor/custom.py create mode 100644 esphomeyaml/cpp_generator.py create mode 100644 esphomeyaml/cpp_helpers.py create mode 100644 esphomeyaml/cpp_types.py create mode 100644 esphomeyaml/storage_json.py diff --git a/esphomeyaml/__main__.py b/esphomeyaml/__main__.py index af6c3223e0..185d930b45 100644 --- a/esphomeyaml/__main__.py +++ b/esphomeyaml/__main__.py @@ -2,21 +2,21 @@ from __future__ import print_function import argparse from collections import OrderedDict +from datetime import datetime import logging import os import random import sys -from datetime import datetime -from esphomeyaml import const, core, core_config, mqtt, wizard, writer, yaml_util, platformio_api +from esphomeyaml import const, core, core_config, mqtt, platformio_api, wizard, writer, yaml_util from esphomeyaml.config import get_component, iter_components, read_config -from esphomeyaml.const import CONF_BAUD_RATE, CONF_BUILD_PATH, CONF_DOMAIN, CONF_ESPHOMEYAML, \ +from esphomeyaml.const import CONF_BAUD_RATE, CONF_DOMAIN, CONF_ESPHOMEYAML, \ CONF_HOSTNAME, CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_USE_CUSTOM_CODE, \ - CONF_WIFI, ESP_PLATFORM_ESP8266 -from esphomeyaml.core import ESPHomeYAMLError -from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, \ - _EXPRESSIONS, add, add_job, color, flush_tasks, indent, statement, relative_path -from esphomeyaml.util import safe_print, run_external_command + CONF_WIFI +from esphomeyaml.core import CORE, EsphomeyamlError +from esphomeyaml.cpp_generator import Expression, RawStatement, add, statement +from esphomeyaml.helpers import color, indent +from esphomeyaml.util import run_external_command, safe_print _LOGGER = logging.getLogger(__name__) @@ -32,6 +32,7 @@ def get_serial_ports(): continue if "VID:PID" in info: result.append((port, desc)) + result.sort(key=lambda x: x[0]) return result @@ -94,37 +95,31 @@ def run_miniterm(config, port, escape=False): def write_cpp(config): _LOGGER.info("Generating C++ source...") - add_job(core_config.to_code, config[CONF_ESPHOMEYAML], domain='esphomeyaml') + CORE.add_job(core_config.to_code, config[CONF_ESPHOMEYAML], domain='esphomeyaml') for domain in PRE_INITIALIZE: if domain == CONF_ESPHOMEYAML or domain not in config: continue - add_job(get_component(domain).to_code, config[domain], domain=domain) + CORE.add_job(get_component(domain).to_code, config[domain], domain=domain) for domain, component, conf in iter_components(config): if domain in PRE_INITIALIZE or not hasattr(component, 'to_code'): continue - add_job(component.to_code, conf, domain=domain) + CORE.add_job(component.to_code, conf, domain=domain) - flush_tasks() + CORE.flush_tasks() add(RawStatement('')) add(RawStatement('')) all_code = [] - for exp in _EXPRESSIONS: + for exp in CORE.expressions: if not config[CONF_ESPHOMEYAML][CONF_USE_CUSTOM_CODE]: if isinstance(exp, Expression) and not exp.required: continue - if isinstance(exp, AssignmentExpression) and not exp.obj.required: - if not exp.has_side_effects(): - continue - exp = exp.rhs all_code.append(unicode(statement(exp))) - build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH]) - writer.write_platformio_project(config, build_path) + writer.write_platformio_project() code_s = indent('\n'.join(line.rstrip() for line in all_code)) - cpp_path = os.path.join(build_path, 'src', 'main.cpp') - writer.write_cpp(code_s, cpp_path) + writer.write_cpp(code_s) return 0 @@ -146,8 +141,7 @@ def get_upload_host(config): def upload_using_esptool(config, port): import esptool - build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH]) - path = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin') + path = os.path.join(CORE.build_path, '.pioenvs', CORE.name, 'firmware.bin') cmd = ['esptool.py', '--before', 'default_reset', '--after', 'hard_reset', '--chip', 'esp8266', '--port', port, 'write_flash', '0x0', path] # pylint: disable=protected-access @@ -155,12 +149,10 @@ def upload_using_esptool(config, port): def upload_program(config, args, port): - build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH]) - # if upload is to a serial port use platformio, otherwise assume ota serial_port = port.startswith('/') or port.startswith('COM') if port != 'OTA' and serial_port: - if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266 and args.use_esptoolpy: + if CORE.is_esp8266 and args.use_esptoolpy: return upload_using_esptool(config, port) return platformio_api.run_upload(config, args.verbose, port) @@ -178,7 +170,6 @@ def upload_program(config, args, port): from esphomeyaml.components import ota from esphomeyaml import espota2 - bin_file = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin') if args.host_port is not None: host_port = args.host_port else: @@ -188,11 +179,12 @@ def upload_program(config, args, port): remote_port = ota.get_port(config) password = ota.get_auth(config) - res = espota2.run_ota(host, remote_port, password, bin_file) + res = espota2.run_ota(host, remote_port, password, CORE.firmware_bin) if res == 0: return res _LOGGER.warn("OTA v2 method failed. Trying with legacy OTA...") - return espota2.run_legacy_ota(verbose, host_port, host, remote_port, password, bin_file) + return espota2.run_legacy_ota(verbose, host_port, host, remote_port, password, + CORE.firmware_bin) def show_logs(config, args, port, escape=False): @@ -325,9 +317,8 @@ def command_version(args): def command_clean(args, config): - build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH]) try: - writer.clean_build(build_path) + writer.clean_build() except OSError as err: _LOGGER.error("Error deleting build files: %s", err) return 1 @@ -472,20 +463,21 @@ def run_esphomeyaml(argv): if args.command in PRE_CONFIG_ACTIONS: try: return PRE_CONFIG_ACTIONS[args.command](args) - except ESPHomeYAMLError as e: + except EsphomeyamlError as e: _LOGGER.error(e) return 1 - core.CONFIG_PATH = args.configuration + CORE.config_path = args.configuration - config = read_config(core.CONFIG_PATH) + config = read_config() if config is None: return 1 + CORE.config = config if args.command in POST_CONFIG_ACTIONS: try: return POST_CONFIG_ACTIONS[args.command](args, config) - except ESPHomeYAMLError as e: + except EsphomeyamlError as e: _LOGGER.error(e) return 1 safe_print(u"Unknown command {}".format(args.command)) @@ -495,7 +487,7 @@ def run_esphomeyaml(argv): def main(): try: return run_esphomeyaml(sys.argv) - except ESPHomeYAMLError as e: + except EsphomeyamlError as e: _LOGGER.error(e) return 1 except KeyboardInterrupt: diff --git a/esphomeyaml/automation.py b/esphomeyaml/automation.py index de32e7d39c..aa1c76d91b 100644 --- a/esphomeyaml/automation.py +++ b/esphomeyaml/automation.py @@ -5,13 +5,13 @@ import voluptuous as vol from esphomeyaml import core import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ABOVE, CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, \ - CONF_BELOW, CONF_CONDITION, CONF_CONDITION_ID, CONF_DELAY, \ - CONF_ELSE, CONF_ID, CONF_IF, CONF_LAMBDA, \ - CONF_OR, CONF_RANGE, CONF_THEN, CONF_TRIGGER_ID -from esphomeyaml.core import ESPHomeYAMLError -from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, TemplateArguments, add, add_job, \ - esphomelib_ns, float_, process_lambda, templatable, uint32, get_variable, PollingComponent, \ - Action, Component, Trigger + CONF_BELOW, CONF_CONDITION, CONF_CONDITION_ID, CONF_DELAY, CONF_ELSE, CONF_ID, CONF_IF, \ + CONF_LAMBDA, CONF_OR, CONF_RANGE, CONF_THEN, CONF_TRIGGER_ID +from esphomeyaml.core import CORE, EsphomeyamlError +from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, TemplateArguments, add, \ + get_variable, process_lambda, templatable +from esphomeyaml.cpp_types import Action, App, Component, PollingComponent, Trigger, \ + esphomelib_ns, float_, uint32 from esphomeyaml.util import ServiceRegistry @@ -130,7 +130,6 @@ AUTOMATION_SCHEMA = vol.Schema({ def build_condition(config, arg_type): template_arg = TemplateArguments(arg_type) if isinstance(config, core.Lambda): - lambda_ = None for lambda_ in process_lambda(config, [(arg_type, 'x')]): yield yield LambdaCondition.new(template_arg, lambda_) @@ -149,18 +148,16 @@ def build_condition(config, arg_type): type = RangeCondition.template(template_arg) condition = Pvariable(config[CONF_CONDITION_ID], rhs, type=type) if CONF_ABOVE in conf: - template_ = None for template_ in templatable(conf[CONF_ABOVE], arg_type, float_): yield condition.set_min(template_) if CONF_BELOW in conf: - 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)) + raise EsphomeyamlError(u"Unsupported condition {}".format(config)) def build_conditions(config, arg_type): @@ -280,4 +277,4 @@ def build_automation_(trigger, arg_type, config): def build_automation(trigger, arg_type, config): - add_job(build_automation_, trigger, arg_type, config) + CORE.add_job(build_automation_, trigger, arg_type, config) diff --git a/esphomeyaml/components/ads1115.py b/esphomeyaml/components/ads1115.py index d8d1d9b7cd..d3c2a80de9 100644 --- a/esphomeyaml/components/ads1115.py +++ b/esphomeyaml/components/ads1115.py @@ -1,9 +1,11 @@ import voluptuous as vol -from esphomeyaml.components import sensor, i2c +from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_ID -from esphomeyaml.helpers import App, Pvariable, setup_component, Component +from esphomeyaml.cpp_generator import Pvariable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/binary_sensor/__init__.py b/esphomeyaml/components/binary_sensor/__init__.py index e4cf8a264b..b9914725a5 100644 --- a/esphomeyaml/components/binary_sensor/__init__.py +++ b/esphomeyaml/components/binary_sensor/__init__.py @@ -2,15 +2,17 @@ import voluptuous as vol from esphomeyaml import automation, core from esphomeyaml.components import mqtt +from esphomeyaml.components.mqtt import setup_mqtt_component import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_DELAYED_OFF, CONF_DELAYED_ON, CONF_DEVICE_CLASS, CONF_FILTERS, \ CONF_HEARTBEAT, CONF_ID, CONF_INTERNAL, CONF_INVALID_COOLDOWN, CONF_INVERT, CONF_INVERTED, \ CONF_LAMBDA, CONF_MAX_LENGTH, CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, \ CONF_ON_DOUBLE_CLICK, CONF_ON_MULTI_CLICK, CONF_ON_PRESS, CONF_ON_RELEASE, CONF_STATE, \ CONF_TIMING, CONF_TRIGGER_ID -from esphomeyaml.helpers import App, ArrayInitializer, NoArg, Pvariable, StructInitializer, add, \ - add_job, bool_, esphomelib_ns, process_lambda, setup_mqtt_component, Nameable, Trigger, \ - Component +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import process_lambda, ArrayInitializer, add, Pvariable, \ + StructInitializer +from esphomeyaml.cpp_types import esphomelib_ns, Nameable, Trigger, NoArg, Component, App, bool_ DEVICE_CLASSES = [ '', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas', @@ -25,6 +27,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ binary_sensor_ns = esphomelib_ns.namespace('binary_sensor') BinarySensor = binary_sensor_ns.class_('BinarySensor', Nameable) +BinarySensorPtr = BinarySensor.operator('ptr') MQTTBinarySensorComponent = binary_sensor_ns.class_('MQTTBinarySensorComponent', mqtt.MQTTComponent) # Triggers @@ -269,14 +272,14 @@ def setup_binary_sensor(binary_sensor_obj, mqtt_obj, config): has_side_effects=False) mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) - add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config) + CORE.add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config) def register_binary_sensor(var, config): binary_sensor_var = Pvariable(config[CONF_ID], var, has_side_effects=True) rhs = App.register_binary_sensor(binary_sensor_var) mqtt_var = Pvariable(config[CONF_MQTT_ID], rhs, has_side_effects=True) - add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config) + CORE.add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config) def core_to_hass_config(data, config): diff --git a/esphomeyaml/components/binary_sensor/custom.py b/esphomeyaml/components/binary_sensor/custom.py new file mode 100644 index 0000000000..e56592d40a --- /dev/null +++ b/esphomeyaml/components/binary_sensor/custom.py @@ -0,0 +1,37 @@ +import voluptuous as vol + +from esphomeyaml.components import binary_sensor +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_BINARY_SENSORS, CONF_ID, CONF_LAMBDA +from esphomeyaml.cpp_generator import process_lambda +from esphomeyaml.cpp_types import std_vector + +CustomBinarySensorConstructor = binary_sensor.binary_sensor_ns.class_( + 'CustomBinarySensorConstructor') + +PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(CustomBinarySensorConstructor), + vol.Required(CONF_LAMBDA): cv.lambda_, + vol.Required(CONF_BINARY_SENSORS): + vol.All(cv.ensure_list, [binary_sensor.BINARY_SENSOR_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(binary_sensor.BinarySensor), + })]), +}) + + +def to_code(config): + for template_ in process_lambda(config[CONF_LAMBDA], [], + return_type=std_vector.template(binary_sensor.BinarySensorPtr)): + yield + + rhs = CustomBinarySensorConstructor(template_) + custom = variable(config[CONF_ID], rhs) + for i, sens in enumerate(config[CONF_BINARY_SENSORS]): + binary_sensor.register_binary_sensor(custom.get_binary_sensor(i), sens) + + +BUILD_FLAGS = '-DUSE_CUSTOM_BINARY_SENSOR' + + +def to_hass_config(data, config): + return [binary_sensor.core_to_hass_config(data, sens) for sens in config[CONF_BINARY_SENSORS]] diff --git a/esphomeyaml/components/binary_sensor/esp32_ble_tracker.py b/esphomeyaml/components/binary_sensor/esp32_ble_tracker.py index 63e08a0baf..25c389e2cd 100644 --- a/esphomeyaml/components/binary_sensor/esp32_ble_tracker.py +++ b/esphomeyaml/components/binary_sensor/esp32_ble_tracker.py @@ -5,7 +5,8 @@ from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLE make_address_array import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME -from esphomeyaml.helpers import esphomelib_ns, get_variable +from esphomeyaml.cpp_generator import get_variable +from esphomeyaml.cpp_types import esphomelib_ns DEPENDENCIES = ['esp32_ble_tracker'] ESP32BLEPresenceDevice = esphomelib_ns.class_('ESP32BLEPresenceDevice', binary_sensor.BinarySensor) diff --git a/esphomeyaml/components/binary_sensor/esp32_touch.py b/esphomeyaml/components/binary_sensor/esp32_touch.py index fcf01e664c..6c90846276 100644 --- a/esphomeyaml/components/binary_sensor/esp32_touch.py +++ b/esphomeyaml/components/binary_sensor/esp32_touch.py @@ -4,7 +4,8 @@ import esphomeyaml.config_validation as cv from esphomeyaml.components import binary_sensor from esphomeyaml.components.esp32_touch import ESP32TouchComponent from esphomeyaml.const import CONF_NAME, CONF_PIN, CONF_THRESHOLD, ESP_PLATFORM_ESP32 -from esphomeyaml.helpers import get_variable, global_ns +from esphomeyaml.cpp_generator import get_variable +from esphomeyaml.cpp_types import global_ns from esphomeyaml.pins import validate_gpio_pin ESP_PLATFORMS = [ESP_PLATFORM_ESP32] diff --git a/esphomeyaml/components/binary_sensor/gpio.py b/esphomeyaml/components/binary_sensor/gpio.py index 80a6d2b487..feb470d299 100644 --- a/esphomeyaml/components/binary_sensor/gpio.py +++ b/esphomeyaml/components/binary_sensor/gpio.py @@ -4,8 +4,9 @@ import esphomeyaml.config_validation as cv from esphomeyaml import pins 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, \ - setup_component, Component +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component +from esphomeyaml.cpp_types import Application, Component, App MakeGPIOBinarySensor = Application.struct('MakeGPIOBinarySensor') GPIOBinarySensorComponent = binary_sensor.binary_sensor_ns.class_('GPIOBinarySensorComponent', diff --git a/esphomeyaml/components/binary_sensor/nextion.py b/esphomeyaml/components/binary_sensor/nextion.py index 162392d223..ff4e9d34d2 100644 --- a/esphomeyaml/components/binary_sensor/nextion.py +++ b/esphomeyaml/components/binary_sensor/nextion.py @@ -4,7 +4,7 @@ from esphomeyaml.components import binary_sensor, display from esphomeyaml.components.display.nextion import Nextion import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_COMPONENT_ID, CONF_NAME, CONF_PAGE_ID -from esphomeyaml.helpers import get_variable +from esphomeyaml.cpp_generator import get_variable DEPENDENCIES = ['display'] @@ -22,7 +22,6 @@ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend def to_code(config): - hub = None for hub in get_variable(config[CONF_NEXTION_ID]): yield rhs = hub.make_touch_component(config[CONF_NAME], config[CONF_PAGE_ID], diff --git a/esphomeyaml/components/binary_sensor/pn532.py b/esphomeyaml/components/binary_sensor/pn532.py index 38031b650c..f0681ff6d7 100644 --- a/esphomeyaml/components/binary_sensor/pn532.py +++ b/esphomeyaml/components/binary_sensor/pn532.py @@ -5,7 +5,7 @@ from esphomeyaml.components import binary_sensor from esphomeyaml.components.pn532 import PN532Component from esphomeyaml.const import CONF_NAME, CONF_UID from esphomeyaml.core import HexInt -from esphomeyaml.helpers import ArrayInitializer, get_variable +from esphomeyaml.cpp_generator import get_variable, ArrayInitializer DEPENDENCIES = ['pn532'] diff --git a/esphomeyaml/components/binary_sensor/rdm6300.py b/esphomeyaml/components/binary_sensor/rdm6300.py index c4a11e4f31..24aa69f0fa 100644 --- a/esphomeyaml/components/binary_sensor/rdm6300.py +++ b/esphomeyaml/components/binary_sensor/rdm6300.py @@ -3,7 +3,7 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml.components import binary_sensor, rdm6300 from esphomeyaml.const import CONF_NAME, CONF_UID -from esphomeyaml.helpers import get_variable +from esphomeyaml.cpp_generator import get_variable DEPENDENCIES = ['rdm6300'] diff --git a/esphomeyaml/components/binary_sensor/remote_receiver.py b/esphomeyaml/components/binary_sensor/remote_receiver.py index 4d66caca44..3cba577771 100644 --- a/esphomeyaml/components/binary_sensor/remote_receiver.py +++ b/esphomeyaml/components/binary_sensor/remote_receiver.py @@ -11,7 +11,7 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_CHANNEL, CONF_CODE, CONF_COMMAN CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, CONF_RC_SWITCH_TYPE_A, \ CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, CONF_SAMSUNG, CONF_SONY, \ CONF_STATE -from esphomeyaml.helpers import ArrayInitializer, Pvariable, get_variable +from esphomeyaml.cpp_generator import ArrayInitializer, get_variable, Pvariable DEPENDENCIES = ['remote_receiver'] diff --git a/esphomeyaml/components/binary_sensor/status.py b/esphomeyaml/components/binary_sensor/status.py index 5fca06cf93..3187de4353 100644 --- a/esphomeyaml/components/binary_sensor/status.py +++ b/esphomeyaml/components/binary_sensor/status.py @@ -1,7 +1,9 @@ import esphomeyaml.config_validation as cv from esphomeyaml.components import binary_sensor from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME -from esphomeyaml.helpers import App, Application, variable, setup_component, Component +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, Component, App DEPENDENCIES = ['mqtt'] diff --git a/esphomeyaml/components/binary_sensor/template.py b/esphomeyaml/components/binary_sensor/template.py index 3369b50aab..3078d56779 100644 --- a/esphomeyaml/components/binary_sensor/template.py +++ b/esphomeyaml/components/binary_sensor/template.py @@ -3,8 +3,9 @@ import voluptuous as vol from esphomeyaml.components import binary_sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME -from esphomeyaml.helpers import App, Application, add, bool_, optional, process_lambda, variable, \ - setup_component, Component +from esphomeyaml.cpp_generator import variable, process_lambda, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, Component, App, optional, bool_ MakeTemplateBinarySensor = Application.struct('MakeTemplateBinarySensor') TemplateBinarySensor = binary_sensor.binary_sensor_ns.class_('TemplateBinarySensor', diff --git a/esphomeyaml/components/cover/__init__.py b/esphomeyaml/components/cover/__init__.py index a121ce9b08..c6bbeb5f81 100644 --- a/esphomeyaml/components/cover/__init__.py +++ b/esphomeyaml/components/cover/__init__.py @@ -1,11 +1,12 @@ import voluptuous as vol -from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY +from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id from esphomeyaml.components import mqtt +from esphomeyaml.components.mqtt import setup_mqtt_component import esphomeyaml.config_validation as cv -from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_INTERNAL -from esphomeyaml.helpers import Pvariable, esphomelib_ns, setup_mqtt_component, add, \ - TemplateArguments, get_variable, Action, Nameable +from esphomeyaml.const import CONF_ID, CONF_INTERNAL, CONF_MQTT_ID +from esphomeyaml.cpp_generator import Pvariable, TemplateArguments, add, get_variable +from esphomeyaml.cpp_types import Action, Nameable, esphomelib_ns PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ diff --git a/esphomeyaml/components/cover/template.py b/esphomeyaml/components/cover/template.py index 564c13ceb4..f29b7b5c91 100644 --- a/esphomeyaml/components/cover/template.py +++ b/esphomeyaml/components/cover/template.py @@ -5,8 +5,9 @@ from esphomeyaml import automation from esphomeyaml.components import cover from esphomeyaml.const import CONF_CLOSE_ACTION, CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, \ CONF_OPEN_ACTION, CONF_STOP_ACTION, CONF_OPTIMISTIC -from esphomeyaml.helpers import App, Application, NoArg, add, process_lambda, variable, optional, \ - setup_component +from esphomeyaml.cpp_generator import variable, process_lambda, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, App, optional, NoArg MakeTemplateCover = Application.struct('MakeTemplateCover') TemplateCover = cover.cover_ns.class_('TemplateCover', cover.Cover) diff --git a/esphomeyaml/components/dallas.py b/esphomeyaml/components/dallas.py index eae9fa9c82..68d1c3d86a 100644 --- a/esphomeyaml/components/dallas.py +++ b/esphomeyaml/components/dallas.py @@ -1,16 +1,18 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import sensor +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ID, CONF_PIN, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Pvariable, setup_component, PollingComponent +from esphomeyaml.cpp_generator import Pvariable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, PollingComponent DallasComponent = sensor.sensor_ns.class_('DallasComponent', PollingComponent) CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({ cv.GenerateID(): cv.declare_variable_id(DallasComponent), - vol.Required(CONF_PIN): pins.input_output_pin, + vol.Required(CONF_PIN): pins.input_pullup_pin, vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval, }).extend(cv.COMPONENT_SCHEMA.schema)]) diff --git a/esphomeyaml/components/debug.py b/esphomeyaml/components/debug.py index 533ffb8114..5751f1517f 100644 --- a/esphomeyaml/components/debug.py +++ b/esphomeyaml/components/debug.py @@ -1,6 +1,7 @@ import voluptuous as vol -from esphomeyaml.helpers import App, add +from esphomeyaml.cpp_generator import add +from esphomeyaml.cpp_types import App DEPENDENCIES = ['logger'] diff --git a/esphomeyaml/components/deep_sleep.py b/esphomeyaml/components/deep_sleep.py index 4b5f57c2f5..12b5fd677c 100644 --- a/esphomeyaml/components/deep_sleep.py +++ b/esphomeyaml/components/deep_sleep.py @@ -2,11 +2,12 @@ import voluptuous as vol from esphomeyaml import config_validation as cv, pins from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id -from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_RUN_CYCLES, CONF_RUN_DURATION, \ - CONF_SLEEP_DURATION, CONF_WAKEUP_PIN, CONF_MODE, CONF_PINS -from esphomeyaml.helpers import Action, App, Component, Pvariable, TemplateArguments, add, \ - esphomelib_ns, get_variable, gpio_input_pin_expression, setup_component, global_ns, \ - StructInitializer +from esphomeyaml.const import CONF_ID, CONF_MODE, CONF_NUMBER, CONF_PINS, CONF_RUN_CYCLES, \ + CONF_RUN_DURATION, CONF_SLEEP_DURATION, CONF_WAKEUP_PIN +from esphomeyaml.cpp_generator import Pvariable, StructInitializer, TemplateArguments, add, \ + get_variable +from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component +from esphomeyaml.cpp_types import Action, App, Component, esphomelib_ns, global_ns def validate_pin_number(value): diff --git a/esphomeyaml/components/display/__init__.py b/esphomeyaml/components/display/__init__.py index ffcaabecb6..c05946f55c 100644 --- a/esphomeyaml/components/display/__init__.py +++ b/esphomeyaml/components/display/__init__.py @@ -1,9 +1,11 @@ # coding=utf-8 import voluptuous as vol +from esphomeyaml.components.text_sensor import add_job import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_LAMBDA, CONF_ROTATION, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import add, add_job, esphomelib_ns +from esphomeyaml.cpp_generator import add +from esphomeyaml.cpp_types import esphomelib_ns PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ diff --git a/esphomeyaml/components/display/lcd_gpio.py b/esphomeyaml/components/display/lcd_gpio.py index d36ac780e8..c0264618ff 100644 --- a/esphomeyaml/components/display/lcd_gpio.py +++ b/esphomeyaml/components/display/lcd_gpio.py @@ -1,12 +1,13 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import display +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_DATA_PINS, CONF_DIMENSIONS, CONF_ENABLE_PIN, CONF_ID, \ CONF_LAMBDA, CONF_RS_PIN, CONF_RW_PIN -from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression, process_lambda, \ - setup_component, PollingComponent +from esphomeyaml.cpp_generator import Pvariable, add, process_lambda +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, PollingComponent LCDDisplay = display.display_ns.class_('LCDDisplay', PollingComponent) LCDDisplayRef = LCDDisplay.operator('ref') diff --git a/esphomeyaml/components/display/lcd_pcf8574.py b/esphomeyaml/components/display/lcd_pcf8574.py index 761203c212..f967f259d1 100644 --- a/esphomeyaml/components/display/lcd_pcf8574.py +++ b/esphomeyaml/components/display/lcd_pcf8574.py @@ -1,11 +1,13 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import display, i2c -from esphomeyaml.components.display.lcd_gpio import LCDDisplayRef, validate_lcd_dimensions, \ - LCDDisplay +from esphomeyaml.components.display.lcd_gpio import LCDDisplay, LCDDisplayRef, \ + validate_lcd_dimensions +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_DIMENSIONS, CONF_ID, CONF_LAMBDA -from esphomeyaml.helpers import App, Pvariable, add, process_lambda, setup_component +from esphomeyaml.cpp_generator import Pvariable, add, process_lambda +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/display/max7219.py b/esphomeyaml/components/display/max7219.py index b5bf380c4d..7283d5932e 100644 --- a/esphomeyaml/components/display/max7219.py +++ b/esphomeyaml/components/display/max7219.py @@ -1,13 +1,14 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import display, spi from esphomeyaml.components.spi import SPIComponent +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_INTENSITY, CONF_LAMBDA, CONF_NUM_CHIPS, \ CONF_SPI_ID -from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_output_pin_expression, \ - process_lambda, setup_component, PollingComponent +from esphomeyaml.cpp_generator import Pvariable, add, get_variable, process_lambda +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, PollingComponent DEPENDENCIES = ['spi'] diff --git a/esphomeyaml/components/display/nextion.py b/esphomeyaml/components/display/nextion.py index 9f26647f96..254a76eddf 100644 --- a/esphomeyaml/components/display/nextion.py +++ b/esphomeyaml/components/display/nextion.py @@ -2,9 +2,9 @@ from esphomeyaml.components import display, uart from esphomeyaml.components.uart import UARTComponent import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_UART_ID -from esphomeyaml.helpers import App, PollingComponent, Pvariable, add, get_variable, \ - process_lambda, \ - setup_component +from esphomeyaml.cpp_generator import Pvariable, add, get_variable, process_lambda +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, PollingComponent DEPENDENCIES = ['uart'] diff --git a/esphomeyaml/components/display/ssd1306_i2c.py b/esphomeyaml/components/display/ssd1306_i2c.py index a80ba8d5b5..27a77018b5 100644 --- a/esphomeyaml/components/display/ssd1306_i2c.py +++ b/esphomeyaml/components/display/ssd1306_i2c.py @@ -1,13 +1,14 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import display from esphomeyaml.components.display import ssd1306_spi -from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, \ - CONF_MODEL, CONF_RESET_PIN, CONF_LAMBDA -from esphomeyaml.helpers import App, Pvariable, add, \ - gpio_output_pin_expression, process_lambda, setup_component +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, CONF_LAMBDA, CONF_MODEL, \ + CONF_RESET_PIN +from esphomeyaml.cpp_generator import Pvariable, add, process_lambda +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/display/ssd1306_spi.py b/esphomeyaml/components/display/ssd1306_spi.py index bf47a5e92a..d2a3deab21 100644 --- a/esphomeyaml/components/display/ssd1306_spi.py +++ b/esphomeyaml/components/display/ssd1306_spi.py @@ -1,14 +1,14 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import display, spi from esphomeyaml.components.spi import SPIComponent -from esphomeyaml.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, \ - CONF_ID, CONF_MODEL, \ - CONF_RESET_PIN, CONF_SPI_ID, CONF_LAMBDA -from esphomeyaml.helpers import App, Pvariable, add, get_variable, \ - gpio_output_pin_expression, process_lambda, setup_component, PollingComponent +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, CONF_ID, CONF_LAMBDA, \ + CONF_MODEL, CONF_RESET_PIN, CONF_SPI_ID +from esphomeyaml.cpp_generator import Pvariable, add, get_variable, process_lambda +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, PollingComponent DEPENDENCIES = ['spi'] diff --git a/esphomeyaml/components/display/waveshare_epaper.py b/esphomeyaml/components/display/waveshare_epaper.py index 51723440cf..50bdc010c4 100644 --- a/esphomeyaml/components/display/waveshare_epaper.py +++ b/esphomeyaml/components/display/waveshare_epaper.py @@ -6,8 +6,10 @@ from esphomeyaml.components import display, spi from esphomeyaml.components.spi import SPIComponent from esphomeyaml.const import CONF_BUSY_PIN, CONF_CS_PIN, CONF_DC_PIN, CONF_FULL_UPDATE_EVERY, \ CONF_ID, CONF_LAMBDA, CONF_MODEL, CONF_RESET_PIN, CONF_SPI_ID -from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_input_pin_expression, \ - gpio_output_pin_expression, process_lambda, setup_component, PollingComponent +from esphomeyaml.cpp_generator import get_variable, Pvariable, process_lambda, add +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, gpio_input_pin_expression, \ + setup_component +from esphomeyaml.cpp_types import PollingComponent, App DEPENDENCIES = ['spi'] diff --git a/esphomeyaml/components/esp32_ble_beacon.py b/esphomeyaml/components/esp32_ble_beacon.py index 2d9e8d37a4..5d05909069 100644 --- a/esphomeyaml/components/esp32_ble_beacon.py +++ b/esphomeyaml/components/esp32_ble_beacon.py @@ -2,8 +2,9 @@ import voluptuous as vol from esphomeyaml import config_validation as cv from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, CONF_TYPE, CONF_UUID, ESP_PLATFORM_ESP32 -from esphomeyaml.helpers import App, ArrayInitializer, Component, Pvariable, RawExpression, add, \ - esphomelib_ns, setup_component +from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, RawExpression, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component, esphomelib_ns ESP_PLATFORMS = [ESP_PLATFORM_ESP32] diff --git a/esphomeyaml/components/esp32_ble_tracker.py b/esphomeyaml/components/esp32_ble_tracker.py index 40be12590a..00f8834e41 100644 --- a/esphomeyaml/components/esp32_ble_tracker.py +++ b/esphomeyaml/components/esp32_ble_tracker.py @@ -4,8 +4,9 @@ from esphomeyaml import config_validation as cv from esphomeyaml.components import sensor from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32 from esphomeyaml.core import HexInt -from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, ArrayInitializer, \ - setup_component, Component +from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component, esphomelib_ns ESP_PLATFORMS = [ESP_PLATFORM_ESP32] diff --git a/esphomeyaml/components/esp32_touch.py b/esphomeyaml/components/esp32_touch.py index 0591e1e92f..e6eb33e6e0 100644 --- a/esphomeyaml/components/esp32_touch.py +++ b/esphomeyaml/components/esp32_touch.py @@ -2,11 +2,13 @@ import voluptuous as vol from esphomeyaml import config_validation as cv from esphomeyaml.components import binary_sensor -from esphomeyaml.const import CONF_ID, CONF_SETUP_MODE, CONF_IIR_FILTER, \ - CONF_SLEEP_DURATION, CONF_MEASUREMENT_DURATION, CONF_LOW_VOLTAGE_REFERENCE, \ - CONF_HIGH_VOLTAGE_REFERENCE, CONF_VOLTAGE_ATTENUATION, ESP_PLATFORM_ESP32 +from esphomeyaml.const import CONF_HIGH_VOLTAGE_REFERENCE, CONF_ID, CONF_IIR_FILTER, \ + CONF_LOW_VOLTAGE_REFERENCE, CONF_MEASUREMENT_DURATION, CONF_SETUP_MODE, CONF_SLEEP_DURATION, \ + CONF_VOLTAGE_ATTENUATION, ESP_PLATFORM_ESP32 from esphomeyaml.core import TimePeriod -from esphomeyaml.helpers import App, Pvariable, add, global_ns, setup_component, Component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component, global_ns ESP_PLATFORMS = [ESP_PLATFORM_ESP32] @@ -19,6 +21,7 @@ def validate_voltage(values): if not value.endswith('V'): value += 'V' return cv.one_of(*values)(value) + return validator diff --git a/esphomeyaml/components/fan/__init__.py b/esphomeyaml/components/fan/__init__.py index 9874c4114f..92df54be0d 100644 --- a/esphomeyaml/components/fan/__init__.py +++ b/esphomeyaml/components/fan/__init__.py @@ -1,13 +1,14 @@ import voluptuous as vol -from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY +from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id from esphomeyaml.components import mqtt +from esphomeyaml.components.mqtt import setup_mqtt_component import esphomeyaml.config_validation as cv -from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_OSCILLATION_COMMAND_TOPIC, \ - CONF_OSCILLATION_STATE_TOPIC, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC, CONF_INTERNAL, \ - CONF_SPEED, CONF_OSCILLATING, CONF_OSCILLATION_OUTPUT, CONF_NAME -from esphomeyaml.helpers import Application, Pvariable, add, esphomelib_ns, setup_mqtt_component, \ - TemplateArguments, get_variable, templatable, bool_, Action, Nameable, Component +from esphomeyaml.const import CONF_ID, CONF_INTERNAL, CONF_MQTT_ID, CONF_NAME, CONF_OSCILLATING, \ + CONF_OSCILLATION_COMMAND_TOPIC, CONF_OSCILLATION_OUTPUT, CONF_OSCILLATION_STATE_TOPIC, \ + CONF_SPEED, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC +from esphomeyaml.cpp_generator import add, Pvariable, get_variable, TemplateArguments, templatable +from esphomeyaml.cpp_types import Application, Component, Nameable, esphomelib_ns, Action, bool_ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ @@ -38,7 +39,6 @@ FAN_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ FAN_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(FAN_SCHEMA.schema) - FAN_SPEEDS = { 'OFF': FAN_SPEED_OFF, 'LOW': FAN_SPEED_LOW, @@ -74,7 +74,6 @@ def setup_fan(fan_obj, mqtt_obj, config): BUILD_FLAGS = '-DUSE_FAN' - CONF_FAN_TOGGLE = 'fan.toggle' FAN_TOGGLE_ACTION_SCHEMA = maybe_simple_id({ vol.Required(CONF_ID): cv.use_variable_id(FanState), diff --git a/esphomeyaml/components/fan/binary.py b/esphomeyaml/components/fan/binary.py index 1ce51c2a0b..f4dd31b2f3 100644 --- a/esphomeyaml/components/fan/binary.py +++ b/esphomeyaml/components/fan/binary.py @@ -3,7 +3,9 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml.components import fan, output from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OSCILLATION_OUTPUT, CONF_OUTPUT -from esphomeyaml.helpers import App, add, get_variable, variable, setup_component +from esphomeyaml.cpp_generator import get_variable, variable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App PLATFORM_SCHEMA = cv.nameable(fan.FAN_PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(fan.MakeFan), diff --git a/esphomeyaml/components/fan/speed.py b/esphomeyaml/components/fan/speed.py index d1259d3ae1..8ad8944fc6 100644 --- a/esphomeyaml/components/fan/speed.py +++ b/esphomeyaml/components/fan/speed.py @@ -5,7 +5,8 @@ from esphomeyaml.components import fan, mqtt, output from esphomeyaml.const import CONF_HIGH, CONF_LOW, CONF_MAKE_ID, CONF_MEDIUM, CONF_NAME, \ CONF_OSCILLATION_OUTPUT, CONF_OUTPUT, CONF_SPEED, CONF_SPEED_COMMAND_TOPIC, \ CONF_SPEED_STATE_TOPIC -from esphomeyaml.helpers import App, add, get_variable, variable +from esphomeyaml.cpp_generator import get_variable, variable, add +from esphomeyaml.cpp_types import App PLATFORM_SCHEMA = cv.nameable(fan.FAN_PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(fan.MakeFan), diff --git a/esphomeyaml/components/font.py b/esphomeyaml/components/font.py index 1456c3e717..f93abf0d48 100644 --- a/esphomeyaml/components/font.py +++ b/esphomeyaml/components/font.py @@ -1,13 +1,13 @@ # coding=utf-8 import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import core from esphomeyaml.components import display +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE -from esphomeyaml.core import HexInt -from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add, \ - relative_path +from esphomeyaml.core import CORE, HexInt +from esphomeyaml.cpp_generator import ArrayInitializer, MockObj, Pvariable, RawExpression, add +from esphomeyaml.cpp_types import App DEPENDENCIES = ['display'] @@ -83,11 +83,11 @@ def to_code(config): from PIL import ImageFont for conf in config: - path = relative_path(conf[CONF_FILE]) + path = CORE.relative_path(conf[CONF_FILE]) try: font = ImageFont.truetype(path, conf[CONF_SIZE]) except Exception as e: - raise core.ESPHomeYAMLError(u"Could not load truetype file {}: {}".format(path, e)) + raise core.EsphomeyamlError(u"Could not load truetype file {}: {}".format(path, e)) ascent, descent = font.getmetrics() diff --git a/esphomeyaml/components/globals.py b/esphomeyaml/components/globals.py index d9a6cf0978..dd4e5c2160 100644 --- a/esphomeyaml/components/globals.py +++ b/esphomeyaml/components/globals.py @@ -2,8 +2,9 @@ import voluptuous as vol from esphomeyaml import config_validation as cv from esphomeyaml.const import CONF_ID, CONF_INITIAL_VALUE, CONF_RESTORE_VALUE, CONF_TYPE -from esphomeyaml.helpers import App, Component, Pvariable, RawExpression, TemplateArguments, add, \ - esphomelib_ns, setup_component +from esphomeyaml.cpp_generator import Pvariable, RawExpression, TemplateArguments, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component, esphomelib_ns GlobalVariableComponent = esphomelib_ns.class_('GlobalVariableComponent', Component) diff --git a/esphomeyaml/components/i2c.py b/esphomeyaml/components/i2c.py index 133b3031c6..2a37613c9b 100644 --- a/esphomeyaml/components/i2c.py +++ b/esphomeyaml/components/i2c.py @@ -1,18 +1,20 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins -from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CONF_ID, \ - CONF_RECEIVE_TIMEOUT -from esphomeyaml.helpers import App, add, Pvariable, esphomelib_ns, setup_component, Component +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_FREQUENCY, CONF_ID, CONF_RECEIVE_TIMEOUT, CONF_SCAN, CONF_SCL, \ + CONF_SDA +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component, esphomelib_ns I2CComponent = esphomelib_ns.class_('I2CComponent', Component) I2CDevice = pins.I2CDevice CONFIG_SCHEMA = vol.Schema({ 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.Required(CONF_SDA, default='SDA'): pins.input_pullup_pin, + vol.Required(CONF_SCL, default='SCL'): pins.input_pullup_pin, vol.Optional(CONF_FREQUENCY): vol.All(cv.frequency, vol.Range(min=0, min_included=False)), vol.Optional(CONF_SCAN): cv.boolean, diff --git a/esphomeyaml/components/image.py b/esphomeyaml/components/image.py index ac0c95be2d..3d321be243 100644 --- a/esphomeyaml/components/image.py +++ b/esphomeyaml/components/image.py @@ -3,13 +3,13 @@ import logging import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import core from esphomeyaml.components import display, font +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_FILE, CONF_ID, CONF_RESIZE -from esphomeyaml.core import HexInt -from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add, \ - relative_path +from esphomeyaml.core import CORE, HexInt +from esphomeyaml.cpp_generator import ArrayInitializer, MockObj, Pvariable, RawExpression, add +from esphomeyaml.cpp_types import App _LOGGER = logging.getLogger(__name__) @@ -33,11 +33,11 @@ def to_code(config): from PIL import Image for conf in config: - path = relative_path(conf[CONF_FILE]) + path = CORE.relative_path(conf[CONF_FILE]) try: image = Image.open(path) except Exception as e: - raise core.ESPHomeYAMLError(u"Could not load image file {}: {}".format(path, e)) + raise core.EsphomeyamlError(u"Could not load image file {}: {}".format(path, e)) if CONF_RESIZE in conf: image.thumbnail(conf[CONF_RESIZE]) diff --git a/esphomeyaml/components/light/__init__.py b/esphomeyaml/components/light/__init__.py index 0262e3b9b0..cb01e9e7c4 100644 --- a/esphomeyaml/components/light/__init__.py +++ b/esphomeyaml/components/light/__init__.py @@ -2,6 +2,7 @@ import voluptuous as vol from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY from esphomeyaml.components import mqtt +from esphomeyaml.components.mqtt import setup_mqtt_component import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ALPHA, CONF_BLUE, CONF_BRIGHTNESS, CONF_COLORS, \ CONF_DEFAULT_TRANSITION_LENGTH, CONF_DURATION, CONF_EFFECTS, CONF_EFFECT_ID, \ @@ -9,10 +10,11 @@ from esphomeyaml.const import CONF_ALPHA, CONF_BLUE, CONF_BRIGHTNESS, CONF_COLOR CONF_NUM_LEDS, CONF_RANDOM, CONF_RED, CONF_SPEED, CONF_STATE, CONF_TRANSITION_LENGTH, \ CONF_UPDATE_INTERVAL, CONF_WHITE, CONF_WIDTH, CONF_FLASH_LENGTH, CONF_COLOR_TEMPERATURE, \ CONF_EFFECT -from esphomeyaml.helpers import Application, ArrayInitializer, Pvariable, RawExpression, \ - StructInitializer, add, add_job, esphomelib_ns, process_lambda, setup_mqtt_component, \ - get_variable, TemplateArguments, templatable, uint32, float_, std_string, Nameable, Component, \ - Action +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import process_lambda, Pvariable, add, StructInitializer, \ + ArrayInitializer, TemplateArguments, get_variable, templatable +from esphomeyaml.cpp_types import esphomelib_ns, Application, Component, Nameable, Action, uint32, \ + float_, std_string PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ @@ -349,7 +351,7 @@ def setup_light_core_(light_var, mqtt_var, config): def setup_light(light_obj, mqtt_obj, config): 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) - add_job(setup_light_core_, light_var, mqtt_var, config) + CORE.add_job(setup_light_core_, light_var, mqtt_var, config) BUILD_FLAGS = '-DUSE_LIGHT' diff --git a/esphomeyaml/components/light/binary.py b/esphomeyaml/components/light/binary.py index 55beec807a..2f705e1d80 100644 --- a/esphomeyaml/components/light/binary.py +++ b/esphomeyaml/components/light/binary.py @@ -3,7 +3,9 @@ import voluptuous as vol from esphomeyaml.components import light, output import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_EFFECTS, CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT -from esphomeyaml.helpers import App, get_variable, setup_component, variable +from esphomeyaml.cpp_generator import get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), diff --git a/esphomeyaml/components/light/cwww.py b/esphomeyaml/components/light/cwww.py index d21139b5a0..c8df6ee203 100644 --- a/esphomeyaml/components/light/cwww.py +++ b/esphomeyaml/components/light/cwww.py @@ -7,7 +7,9 @@ from esphomeyaml.components.light.rgbww import validate_cold_white_colder, \ from esphomeyaml.const import CONF_COLD_WHITE, CONF_COLD_WHITE_COLOR_TEMPERATURE, \ CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \ CONF_NAME, CONF_WARM_WHITE, CONF_WARM_WHITE_COLOR_TEMPERATURE -from esphomeyaml.helpers import App, get_variable, variable, setup_component +from esphomeyaml.cpp_generator import get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), diff --git a/esphomeyaml/components/light/fastled_clockless.py b/esphomeyaml/components/light/fastled_clockless.py index c779f4ceed..6f195fd1de 100644 --- a/esphomeyaml/components/light/fastled_clockless.py +++ b/esphomeyaml/components/light/fastled_clockless.py @@ -1,14 +1,15 @@ 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, CONF_EFFECTS, CONF_COLOR_CORRECT -from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \ - get_variable, variable, setup_component +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_CHIPSET, CONF_COLOR_CORRECT, CONF_DEFAULT_TRANSITION_LENGTH, \ + CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, \ + CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, CONF_RGB_ORDER +from esphomeyaml.cpp_generator import RawExpression, TemplateArguments, add, get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application TYPES = [ 'NEOPIXEL', diff --git a/esphomeyaml/components/light/fastled_spi.py b/esphomeyaml/components/light/fastled_spi.py index bd4df644e3..8ddc2dd53f 100644 --- a/esphomeyaml/components/light/fastled_spi.py +++ b/esphomeyaml/components/light/fastled_spi.py @@ -1,14 +1,15 @@ 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, CONF_EFFECTS, CONF_COLOR_CORRECT -from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \ - get_variable, variable, setup_component +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_COLOR_CORRECT, CONF_DATA_PIN, \ + CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \ + CONF_MAX_REFRESH_RATE, CONF_NAME, CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER +from esphomeyaml.cpp_generator import RawExpression, TemplateArguments, add, get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application CHIPSETS = [ 'LPD8806', diff --git a/esphomeyaml/components/light/monochromatic.py b/esphomeyaml/components/light/monochromatic.py index bed9f65d37..0e9a1ccb48 100644 --- a/esphomeyaml/components/light/monochromatic.py +++ b/esphomeyaml/components/light/monochromatic.py @@ -4,7 +4,9 @@ from esphomeyaml.components import light, output import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, \ CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT -from esphomeyaml.helpers import App, get_variable, setup_component, variable +from esphomeyaml.cpp_generator import get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), diff --git a/esphomeyaml/components/light/rgb.py b/esphomeyaml/components/light/rgb.py index 556ba9b241..11dde11525 100644 --- a/esphomeyaml/components/light/rgb.py +++ b/esphomeyaml/components/light/rgb.py @@ -1,10 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import light, output -from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ - CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_EFFECTS -from esphomeyaml.helpers import App, get_variable, variable, setup_component +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, \ + CONF_GAMMA_CORRECT, CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED +from esphomeyaml.cpp_generator import get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), diff --git a/esphomeyaml/components/light/rgbw.py b/esphomeyaml/components/light/rgbw.py index 07631ca71b..21d41536c8 100644 --- a/esphomeyaml/components/light/rgbw.py +++ b/esphomeyaml/components/light/rgbw.py @@ -1,10 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import light, output -from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ - CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_WHITE, CONF_EFFECTS -from esphomeyaml.helpers import App, get_variable, variable, setup_component +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, \ + CONF_GAMMA_CORRECT, CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_WHITE +from esphomeyaml.cpp_generator import get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), diff --git a/esphomeyaml/components/light/rgbww.py b/esphomeyaml/components/light/rgbww.py index fa7a92d6ff..a6a65116f8 100644 --- a/esphomeyaml/components/light/rgbww.py +++ b/esphomeyaml/components/light/rgbww.py @@ -1,11 +1,13 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import light, output +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_BLUE, CONF_COLD_WHITE, CONF_COLD_WHITE_COLOR_TEMPERATURE, \ CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_GREEN, CONF_MAKE_ID, \ CONF_NAME, CONF_RED, CONF_WARM_WHITE, CONF_WARM_WHITE_COLOR_TEMPERATURE -from esphomeyaml.helpers import App, get_variable, variable, setup_component +from esphomeyaml.cpp_generator import get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App def validate_color_temperature(value): diff --git a/esphomeyaml/components/logger.py b/esphomeyaml/components/logger.py index 839d371d56..88b6d07f3f 100644 --- a/esphomeyaml/components/logger.py +++ b/esphomeyaml/components/logger.py @@ -6,9 +6,10 @@ from esphomeyaml.automation import ACTION_REGISTRY, LambdaAction import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ARGS, CONF_BAUD_RATE, CONF_FORMAT, CONF_ID, CONF_LEVEL, \ CONF_LOGS, CONF_TAG, CONF_TX_BUFFER_SIZE -from esphomeyaml.core import ESPHomeYAMLError, Lambda -from esphomeyaml.helpers import App, Pvariable, RawExpression, TemplateArguments, add, \ - esphomelib_ns, global_ns, process_lambda, statement, Component +from esphomeyaml.core import EsphomeyamlError, Lambda +from esphomeyaml.cpp_generator import Pvariable, add, TemplateArguments, RawExpression, statement, \ + process_lambda +from esphomeyaml.cpp_types import global_ns, esphomelib_ns, Component, App LOG_LEVELS = { 'NONE': global_ns.ESPHOMELIB_LOG_LEVEL_NONE, @@ -39,7 +40,7 @@ def validate_local_no_higher_than_global(value): global_level = value.get(CONF_LEVEL, 'DEBUG') for tag, level in value.get(CONF_LOGS, {}).iteritems(): if LOG_LEVEL_SEVERITY.index(level) > LOG_LEVEL_SEVERITY.index(global_level): - raise ESPHomeYAMLError(u"The local log level {} for {} must be less severe than the " + raise EsphomeyamlError(u"The local log level {} for {} must be less severe than the " u"global log level {}.".format(level, tag, global_level)) return value diff --git a/esphomeyaml/components/mqtt.py b/esphomeyaml/components/mqtt.py index 646ddc0e73..64e6575ba6 100644 --- a/esphomeyaml/components/mqtt.py +++ b/esphomeyaml/components/mqtt.py @@ -7,17 +7,18 @@ from esphomeyaml import automation from esphomeyaml.automation import ACTION_REGISTRY from esphomeyaml.components import logger import esphomeyaml.config_validation as cv -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_LEVEL, \ - CONF_LOG_TOPIC, CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, \ - CONF_REBOOT_TIMEOUT, CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, CONF_TOPIC, \ - CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, CONF_WILL_MESSAGE, CONF_ON_JSON_MESSAGE, \ - CONF_STATE_TOPIC, CONF_MQTT, CONF_ESPHOMEYAML, CONF_NAME, CONF_AVAILABILITY, \ - CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_INTERNAL -from esphomeyaml.core import ESPHomeYAMLError -from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \ - StructInitializer, TemplateArguments, add, esphomelib_ns, optional, std_string, templatable, \ - uint8, bool_, JsonObjectRef, process_lambda, JsonObjectConstRef, Component, Action, Trigger +from esphomeyaml.const import CONF_AVAILABILITY, CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, \ + CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, \ + CONF_ESPHOMEYAML, CONF_ID, CONF_INTERNAL, CONF_KEEPALIVE, CONF_LEVEL, CONF_LOG_TOPIC, \ + CONF_MQTT, CONF_NAME, CONF_ON_JSON_MESSAGE, CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, \ + CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_PORT, CONF_QOS, CONF_REBOOT_TIMEOUT, \ + CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, CONF_STATE_TOPIC, CONF_TOPIC, \ + CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, CONF_WILL_MESSAGE +from esphomeyaml.core import EsphomeyamlError +from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, RawExpression, \ + StructInitializer, TemplateArguments, add, process_lambda, templatable +from esphomeyaml.cpp_types import Action, App, Component, JsonObjectConstRef, JsonObjectRef, \ + Trigger, bool_, esphomelib_ns, optional, std_string, uint8 def validate_message_just_topic(value): @@ -88,7 +89,8 @@ CONFIG_SCHEMA = vol.Schema({ vol.Optional(CONF_ON_MESSAGE): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger), vol.Required(CONF_TOPIC): cv.subscribe_topic, - vol.Optional(CONF_QOS, default=0): cv.mqtt_qos, + vol.Optional(CONF_QOS): cv.mqtt_qos, + vol.Optional(CONF_PAYLOAD): cv.string_strict, }), vol.Optional(CONF_ON_JSON_MESSAGE): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTJsonMessageTrigger), @@ -169,8 +171,12 @@ def to_code(config): add(mqtt.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT])) for conf in config.get(CONF_ON_MESSAGE, []): - rhs = mqtt.make_message_trigger(conf[CONF_TOPIC], conf[CONF_QOS]) + rhs = mqtt.make_message_trigger(conf[CONF_TOPIC]) trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) + if CONF_QOS in conf: + add(trigger.set_qos(conf[CONF_QOS])) + if CONF_PAYLOAD in conf: + add(trigger.set_payload(conf[CONF_PAYLOAD])) automation.build_automation(trigger, std_string, conf) for conf in config.get(CONF_ON_JSON_MESSAGE, []): @@ -282,7 +288,7 @@ def build_hass_config(data, component_type, config, include_state=True, include_ class GenerateHassConfigData(object): def __init__(self, config): if 'mqtt' not in config: - raise ESPHomeYAMLError("Cannot generate Home Assistant MQTT config if MQTT is not " + raise EsphomeyamlError("Cannot generate Home Assistant MQTT config if MQTT is not " "used!") mqtt = config[CONF_MQTT] self.topic_prefix = mqtt.get(CONF_TOPIC_PREFIX, config[CONF_ESPHOMEYAML][CONF_NAME]) @@ -308,3 +314,21 @@ class GenerateHassConfigData(object): CONF_PAYLOAD_AVAILABLE: birth_message[CONF_PAYLOAD], CONF_PAYLOAD_NOT_AVAILABLE: will_message[CONF_PAYLOAD], } + + +def setup_mqtt_component(obj, config): + if CONF_RETAIN in config: + add(obj.set_retain(config[CONF_RETAIN])) + if not config.get(CONF_DISCOVERY, True): + add(obj.disable_discovery()) + if CONF_STATE_TOPIC in config: + add(obj.set_custom_state_topic(config[CONF_STATE_TOPIC])) + if CONF_COMMAND_TOPIC in config: + add(obj.set_custom_command_topic(config[CONF_COMMAND_TOPIC])) + if CONF_AVAILABILITY in config: + availability = config[CONF_AVAILABILITY] + if not availability: + add(obj.disable_availability()) + else: + add(obj.set_availability(availability[CONF_TOPIC], availability[CONF_PAYLOAD_AVAILABLE], + availability[CONF_PAYLOAD_NOT_AVAILABLE])) diff --git a/esphomeyaml/components/my9231.py b/esphomeyaml/components/my9231.py index a52e1b1033..b46b49cc05 100644 --- a/esphomeyaml/components/my9231.py +++ b/esphomeyaml/components/my9231.py @@ -1,17 +1,16 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import output -from esphomeyaml.const import (CONF_DATA_PIN, CONF_CLOCK_PIN, CONF_NUM_CHANNELS, - CONF_NUM_CHIPS, CONF_BIT_DEPTH, CONF_ID, - CONF_UPDATE_ON_BOOT) -from esphomeyaml.helpers import (gpio_output_pin_expression, App, Pvariable, - add, setup_component, Component) +import esphomeyaml.config_validation as cv +from esphomeyaml.const import (CONF_BIT_DEPTH, CONF_CLOCK_PIN, CONF_DATA_PIN, CONF_ID, + CONF_NUM_CHANNELS, CONF_NUM_CHIPS, CONF_UPDATE_ON_BOOT) +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Component MY9231OutputComponent = output.output_ns.class_('MY9231OutputComponent', Component) - MY9231_SCHEMA = vol.Schema({ cv.GenerateID(): cv.declare_variable_id(MY9231OutputComponent), vol.Required(CONF_DATA_PIN): pins.gpio_output_pin_schema, @@ -30,10 +29,8 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [MY9231_SCHEMA]) def to_code(config): for conf in config: - di = None for di in gpio_output_pin_expression(conf[CONF_DATA_PIN]): yield - dcki = None for dcki in gpio_output_pin_expression(conf[CONF_CLOCK_PIN]): yield rhs = App.make_my9231_component(di, dcki) diff --git a/esphomeyaml/components/ota.py b/esphomeyaml/components/ota.py index 83b224cbed..8dbeb51dc5 100644 --- a/esphomeyaml/components/ota.py +++ b/esphomeyaml/components/ota.py @@ -2,12 +2,11 @@ import logging import voluptuous as vol -from esphomeyaml import core import esphomeyaml.config_validation as cv -from esphomeyaml.const import CONF_ID, CONF_OTA, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE, \ - ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 -from esphomeyaml.core import ESPHomeYAMLError -from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, Component +from esphomeyaml.const import CONF_ID, CONF_OTA, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_types import App, Component, esphomelib_ns _LOGGER = logging.getLogger(__name__) @@ -35,11 +34,11 @@ def to_code(config): def get_port(config): if CONF_PORT in config[CONF_OTA]: return config[CONF_OTA][CONF_PORT] - if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: + if CORE.is_esp32: return 3232 - elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: + elif CORE.is_esp8266: return 8266 - raise ESPHomeYAMLError(u"Invalid ESP Platform for ESP OTA port.") + raise NotImplementedError def get_auth(config): @@ -51,6 +50,6 @@ REQUIRED_BUILD_FLAGS = '-DUSE_NEW_OTA' def lib_deps(config): - if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: + if CORE.is_esp32: return ['ArduinoOTA', 'Update', 'ESPmDNS'] return ['Hash', 'ESP8266mDNS', 'ArduinoOTA'] diff --git a/esphomeyaml/components/output/__init__.py b/esphomeyaml/components/output/__init__.py index 6456bd0991..163d378219 100644 --- a/esphomeyaml/components/output/__init__.py +++ b/esphomeyaml/components/output/__init__.py @@ -4,8 +4,9 @@ from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY 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, CONF_ID, CONF_LEVEL -from esphomeyaml.helpers import add, esphomelib_ns, get_variable, TemplateArguments, Pvariable, \ - templatable, float_, add_job, Action +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import add, get_variable, Pvariable, TemplateArguments, templatable +from esphomeyaml.cpp_types import esphomelib_ns, Action, float_ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ @@ -26,7 +27,9 @@ FLOAT_OUTPUT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(FLOAT_OUTPUT_SCHEMA.schema output_ns = esphomelib_ns.namespace('output') BinaryOutput = output_ns.class_('BinaryOutput') +BinaryOutputPtr = BinaryOutput.operator('ptr') FloatOutput = output_ns.class_('FloatOutput', BinaryOutput) +FloatOutputPtr = FloatOutput.operator('ptr') # Actions TurnOffAction = output_ns.class_('TurnOffAction', Action) @@ -47,7 +50,12 @@ def setup_output_platform_(obj, config, skip_power_supply=False): def setup_output_platform(obj, config, skip_power_supply=False): - add_job(setup_output_platform_, obj, config, skip_power_supply) + CORE.add_job(setup_output_platform_, obj, config, skip_power_supply) + + +def register_output(var, config): + output_var = Pvariable(config[CONF_ID], var, has_side_effects=True) + CORE.add_job(setup_output_platform_, output_var, config) BUILD_FLAGS = '-DUSE_OUTPUT' diff --git a/esphomeyaml/components/output/custom.py b/esphomeyaml/components/output/custom.py new file mode 100644 index 0000000000..621b9d878c --- /dev/null +++ b/esphomeyaml/components/output/custom.py @@ -0,0 +1,72 @@ +import voluptuous as vol + +from esphomeyaml.components import binary_sensor, output +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_OUTPUTS, CONF_TYPE +from esphomeyaml.cpp_generator import process_lambda, variable +from esphomeyaml.cpp_types import std_vector + +CustomBinaryOutputConstructor = binary_sensor.binary_sensor_ns.class_( + 'CustomBinaryOutputConstructor') +CustomFloatOutputConstructor = binary_sensor.binary_sensor_ns.class_( + 'CustomFloatOutputConstructor') + +BINARY_SCHEMA = output.PLATFORM_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(CustomBinaryOutputConstructor), + vol.Required(CONF_LAMBDA): cv.lambda_, + vol.Required(CONF_OUTPUTS): + vol.All(cv.ensure_list, [output.BINARY_OUTPUT_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(output.BinaryOutput), + })]), +}) + +FLOAT_SCHEMA = output.PLATFORM_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(CustomFloatOutputConstructor), + vol.Required(CONF_LAMBDA): cv.lambda_, + vol.Required(CONF_OUTPUTS): + vol.All(cv.ensure_list, [output.FLOAT_OUTPUT_PLATFORM_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(output.FloatOutput), + })]), +}) + + +def validate_custom_output(value): + if not isinstance(value, dict): + raise vol.Invalid("Value must be dict") + if CONF_TYPE not in value: + raise vol.Invalid("type not specified!") + type = cv.string_strict(value[CONF_TYPE]).lower() + value[CONF_TYPE] = type + if type == 'binary': + return BINARY_SCHEMA(value) + elif type == 'float': + return FLOAT_SCHEMA(value) + raise vol.Invalid("type must either be binary or float, not {}!".format(type)) + + +PLATFORM_SCHEMA = validate_custom_output + + +def to_code(config): + type = config[CONF_TYPE] + if type == 'binary': + ret_type = output.BinaryOutputPtr + klass = CustomBinaryOutputConstructor + else: + ret_type = output.FloatOutputPtr + klass = CustomFloatOutputConstructor + for template_ in process_lambda(config[CONF_LAMBDA], [], + return_type=std_vector.template(ret_type)): + yield + + rhs = klass(template_) + custom = variable(config[CONF_ID], rhs) + for i, sens in enumerate(config[CONF_OUTPUTS]): + output.register_output(custom.get_output(i), sens) + + +BUILD_FLAGS = '-DUSE_CUSTOM_OUTPUT' + + +def to_hass_config(data, config): + return [binary_sensor.core_to_hass_config(data, sens) for sens in config[CONF_OUTPUTS]] diff --git a/esphomeyaml/components/output/esp8266_pwm.py b/esphomeyaml/components/output/esp8266_pwm.py index c28673742a..009d9487f2 100644 --- a/esphomeyaml/components/output/esp8266_pwm.py +++ b/esphomeyaml/components/output/esp8266_pwm.py @@ -3,9 +3,10 @@ import voluptuous as vol from esphomeyaml import pins from esphomeyaml.components import output import esphomeyaml.config_validation as cv -from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_PIN, ESP_PLATFORM_ESP8266, CONF_FREQUENCY -from esphomeyaml.helpers import App, Component, Pvariable, gpio_output_pin_expression, \ - setup_component, add +from esphomeyaml.const import CONF_FREQUENCY, CONF_ID, CONF_NUMBER, CONF_PIN, ESP_PLATFORM_ESP8266 +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App ESP_PLATFORMS = [ESP_PLATFORM_ESP8266] diff --git a/esphomeyaml/components/output/gpio.py b/esphomeyaml/components/output/gpio.py index 51e3ce27ef..fb4949c1e5 100644 --- a/esphomeyaml/components/output/gpio.py +++ b/esphomeyaml/components/output/gpio.py @@ -1,11 +1,12 @@ import voluptuous as vol from esphomeyaml import pins -import esphomeyaml.config_validation as cv from esphomeyaml.components import output +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ID, CONF_PIN -from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression, setup_component, \ - Component +from esphomeyaml.cpp_generator import Pvariable +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Component GPIOBinaryOutputComponent = output.output_ns.class_('GPIOBinaryOutputComponent', output.BinaryOutput, Component) diff --git a/esphomeyaml/components/output/ledc.py b/esphomeyaml/components/output/ledc.py index 987d44a5be..bd42ba3569 100644 --- a/esphomeyaml/components/output/ledc.py +++ b/esphomeyaml/components/output/ledc.py @@ -1,11 +1,13 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import output +import esphomeyaml.config_validation as cv from esphomeyaml.const import APB_CLOCK_FREQ, CONF_BIT_DEPTH, CONF_CHANNEL, CONF_FREQUENCY, \ CONF_ID, CONF_PIN, ESP_PLATFORM_ESP32 -from esphomeyaml.helpers import App, Pvariable, add, setup_component, Component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component ESP_PLATFORMS = [ESP_PLATFORM_ESP32] diff --git a/esphomeyaml/components/output/my9231.py b/esphomeyaml/components/output/my9231.py index 4669ed2400..ee9f7f494b 100644 --- a/esphomeyaml/components/output/my9231.py +++ b/esphomeyaml/components/output/my9231.py @@ -1,10 +1,11 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import output from esphomeyaml.components.my9231 import MY9231OutputComponent +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_CHANNEL, CONF_ID, CONF_MY9231_ID, CONF_POWER_SUPPLY -from esphomeyaml.helpers import Pvariable, get_variable, setup_component +from esphomeyaml.cpp_generator import Pvariable, get_variable +from esphomeyaml.cpp_helpers import setup_component DEPENDENCIES = ['my9231'] diff --git a/esphomeyaml/components/output/pca9685.py b/esphomeyaml/components/output/pca9685.py index ba2f57ce6d..b43c0f767b 100644 --- a/esphomeyaml/components/output/pca9685.py +++ b/esphomeyaml/components/output/pca9685.py @@ -1,10 +1,10 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import output from esphomeyaml.components.pca9685 import PCA9685OutputComponent +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_CHANNEL, CONF_ID, CONF_PCA9685_ID, CONF_POWER_SUPPLY -from esphomeyaml.helpers import Pvariable, get_variable +from esphomeyaml.cpp_generator import Pvariable, get_variable DEPENDENCIES = ['pca9685'] diff --git a/esphomeyaml/components/pca9685.py b/esphomeyaml/components/pca9685.py index ac3094abaf..06ec49ced8 100644 --- a/esphomeyaml/components/pca9685.py +++ b/esphomeyaml/components/pca9685.py @@ -1,9 +1,11 @@ import voluptuous as vol +from esphomeyaml.components import i2c, output import esphomeyaml.config_validation as cv -from esphomeyaml.components import output, i2c from esphomeyaml.const import CONF_ADDRESS, CONF_FREQUENCY, CONF_ID, CONF_PHASE_BALANCER -from esphomeyaml.helpers import App, HexIntLiteral, Pvariable, add, setup_component, Component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component DEPENDENCIES = ['i2c'] @@ -30,7 +32,7 @@ def to_code(config): rhs = App.make_pca9685_component(conf.get(CONF_FREQUENCY)) pca9685 = Pvariable(conf[CONF_ID], rhs) if CONF_ADDRESS in conf: - add(pca9685.set_address(HexIntLiteral(conf[CONF_ADDRESS]))) + add(pca9685.set_address(conf[CONF_ADDRESS])) setup_component(pca9685, conf) diff --git a/esphomeyaml/components/pcf8574.py b/esphomeyaml/components/pcf8574.py index e2f92d763f..24ac80c671 100644 --- a/esphomeyaml/components/pcf8574.py +++ b/esphomeyaml/components/pcf8574.py @@ -3,7 +3,9 @@ import voluptuous as vol from esphomeyaml import pins import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_PCF8575 -from esphomeyaml.helpers import App, GPIOInputPin, GPIOOutputPin, Pvariable, io_ns, setup_component +from esphomeyaml.cpp_generator import Pvariable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, GPIOInputPin, GPIOOutputPin, io_ns DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/pn532.py b/esphomeyaml/components/pn532.py index a33ac791bd..a7562cc943 100644 --- a/esphomeyaml/components/pn532.py +++ b/esphomeyaml/components/pn532.py @@ -1,13 +1,14 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv -from esphomeyaml import pins, automation +from esphomeyaml import automation, pins from esphomeyaml.components import binary_sensor, spi from esphomeyaml.components.spi import SPIComponent -from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_SPI_ID, CONF_UPDATE_INTERVAL, \ - CONF_ON_TAG, CONF_TRIGGER_ID -from esphomeyaml.helpers import App, Pvariable, get_variable, gpio_output_pin_expression, \ - std_string, setup_component, PollingComponent, Trigger +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_ON_TAG, CONF_SPI_ID, CONF_TRIGGER_ID, \ + CONF_UPDATE_INTERVAL +from esphomeyaml.cpp_generator import Pvariable, get_variable +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, PollingComponent, Trigger, std_string DEPENDENCIES = ['spi'] diff --git a/esphomeyaml/components/power_supply.py b/esphomeyaml/components/power_supply.py index 97efda4f1e..bb69d443f6 100644 --- a/esphomeyaml/components/power_supply.py +++ b/esphomeyaml/components/power_supply.py @@ -1,10 +1,11 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins +import esphomeyaml.config_validation as cv 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, \ - setup_component, Component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Component, esphomelib_ns PowerSupplyComponent = esphomelib_ns.class_('PowerSupplyComponent', Component) diff --git a/esphomeyaml/components/rdm6300.py b/esphomeyaml/components/rdm6300.py index 0ede8e290f..c880ed7f3f 100644 --- a/esphomeyaml/components/rdm6300.py +++ b/esphomeyaml/components/rdm6300.py @@ -1,9 +1,11 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import binary_sensor, uart +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ID, CONF_UART_ID -from esphomeyaml.helpers import App, Pvariable, get_variable, setup_component, Component +from esphomeyaml.cpp_generator import Pvariable, get_variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component DEPENDENCIES = ['uart'] diff --git a/esphomeyaml/components/remote_receiver.py b/esphomeyaml/components/remote_receiver.py index 878e5a6fc5..0076693530 100644 --- a/esphomeyaml/components/remote_receiver.py +++ b/esphomeyaml/components/remote_receiver.py @@ -1,11 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_BUFFER_SIZE, CONF_DUMP, CONF_FILTER, CONF_ID, CONF_IDLE, \ CONF_PIN, CONF_TOLERANCE -from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_input_pin_expression, \ - setup_component, Component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Component, esphomelib_ns remote_ns = esphomelib_ns.namespace('remote') diff --git a/esphomeyaml/components/remote_transmitter.py b/esphomeyaml/components/remote_transmitter.py index 144ac2bfdf..afc89426b6 100644 --- a/esphomeyaml/components/remote_transmitter.py +++ b/esphomeyaml/components/remote_transmitter.py @@ -7,8 +7,9 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_DUTY_PERCENT, CONF_CHAN CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_ID, CONF_INVERTED, CONF_ONE, CONF_PIN, \ CONF_PROTOCOL, CONF_PULSE_LENGTH, CONF_STATE, CONF_SYNC, CONF_ZERO from esphomeyaml.core import HexInt -from esphomeyaml.helpers import App, Component, Pvariable, add, gpio_output_pin_expression, \ - setup_component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Component RemoteTransmitterComponent = remote_ns.class_('RemoteTransmitterComponent', RemoteControlComponentBase, Component) diff --git a/esphomeyaml/components/script.py b/esphomeyaml/components/script.py index 5aab19c3c8..2ab4f74c0d 100644 --- a/esphomeyaml/components/script.py +++ b/esphomeyaml/components/script.py @@ -4,8 +4,8 @@ from esphomeyaml import automation from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ID -from esphomeyaml.helpers import NoArg, Pvariable, TemplateArguments, esphomelib_ns, get_variable, \ - Trigger, Action +from esphomeyaml.cpp_generator import Pvariable, TemplateArguments, get_variable +from esphomeyaml.cpp_types import Action, NoArg, Trigger, esphomelib_ns Script = esphomelib_ns.class_('Script', Trigger.template(NoArg)) ScriptExecuteAction = esphomelib_ns.class_('ScriptExecuteAction', Action) diff --git a/esphomeyaml/components/sensor/__init__.py b/esphomeyaml/components/sensor/__init__.py index 921ce76ae1..8f5df9a470 100644 --- a/esphomeyaml/components/sensor/__init__.py +++ b/esphomeyaml/components/sensor/__init__.py @@ -2,6 +2,7 @@ import voluptuous as vol from esphomeyaml import automation from esphomeyaml.components import mqtt +from esphomeyaml.components.mqtt import setup_mqtt_component import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_BELOW, \ CONF_DEBOUNCE, CONF_DELTA, CONF_EXPIRE_AFTER, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, \ @@ -10,9 +11,10 @@ from esphomeyaml.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CO CONF_ON_VALUE_RANGE, CONF_OR, CONF_SEND_EVERY, CONF_SEND_FIRST_AT, \ CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_THROTTLE, CONF_TRIGGER_ID, CONF_UNIQUE, \ CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE -from esphomeyaml.helpers import App, ArrayInitializer, Component, Nameable, PollingComponent, \ - Pvariable, Trigger, add, add_job, esphomelib_ns, float_, process_lambda, setup_mqtt_component, \ - templatable +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, add, process_lambda, templatable +from esphomeyaml.cpp_types import App, Component, Nameable, PollingComponent, Trigger, \ + esphomelib_ns, float_ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ @@ -188,12 +190,10 @@ def setup_sensor_core_(sensor_var, mqtt_var, config): rhs = sensor_var.make_value_range_trigger() trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) if CONF_ABOVE in conf: - template_ = None for template_ in templatable(conf[CONF_ABOVE], float_, float_): yield add(trigger.set_min(template_)) if CONF_BELOW in conf: - template_ = None for template_ in templatable(conf[CONF_BELOW], float_, float_): yield add(trigger.set_max(template_)) @@ -210,14 +210,14 @@ def setup_sensor_core_(sensor_var, mqtt_var, config): def setup_sensor(sensor_obj, mqtt_obj, 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) - add_job(setup_sensor_core_, sensor_var, mqtt_var, config) + CORE.add_job(setup_sensor_core_, sensor_var, mqtt_var, config) def register_sensor(var, config): sensor_var = Pvariable(config[CONF_ID], var, has_side_effects=True) rhs = App.register_sensor(sensor_var) mqtt_var = Pvariable(config[CONF_MQTT_ID], rhs, has_side_effects=True) - add_job(setup_sensor_core_, sensor_var, mqtt_var, config) + CORE.add_job(setup_sensor_core_, sensor_var, mqtt_var, config) BUILD_FLAGS = '-DUSE_SENSOR' diff --git a/esphomeyaml/components/sensor/adc.py b/esphomeyaml/components/sensor/adc.py index f629ee3d4d..ba8a48c35c 100644 --- a/esphomeyaml/components/sensor/adc.py +++ b/esphomeyaml/components/sensor/adc.py @@ -1,11 +1,13 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import sensor +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ATTENUATION, CONF_MAKE_ID, CONF_NAME, CONF_PIN, \ CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, add, global_ns, variable, setup_component +from esphomeyaml.cpp_generator import add, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, global_ns ATTENUATION_MODES = { '0db': global_ns.ADC_0db, @@ -59,3 +61,9 @@ def required_build_flags(config): def to_hass_config(data, config): return sensor.core_to_hass_config(data, config) + + +def includes(config): + if config[CONF_PIN] == 'VCC': + return 'ADC_MODE(ADC_VCC);' + return None diff --git a/esphomeyaml/components/sensor/ads1115.py b/esphomeyaml/components/sensor/ads1115.py index 5f6c296789..a16f77d079 100644 --- a/esphomeyaml/components/sensor/ads1115.py +++ b/esphomeyaml/components/sensor/ads1115.py @@ -1,11 +1,11 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor from esphomeyaml.components.ads1115 import ADS1115Component +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_NAME, \ CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import get_variable +from esphomeyaml.cpp_generator import get_variable DEPENDENCIES = ['ads1115'] @@ -59,7 +59,6 @@ PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({ def to_code(config): - hub = None for hub in get_variable(config[CONF_ADS1115_ID]): yield diff --git a/esphomeyaml/components/sensor/bh1750.py b/esphomeyaml/components/sensor/bh1750.py index 09057e5f7f..c4f36faaea 100644 --- a/esphomeyaml/components/sensor/bh1750.py +++ b/esphomeyaml/components/sensor/bh1750.py @@ -1,10 +1,12 @@ import voluptuous as vol +from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv -from esphomeyaml.components import sensor, i2c from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_NAME, CONF_RESOLUTION, \ CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, add, variable, setup_component +from esphomeyaml.cpp_generator import add, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/ble_rssi.py b/esphomeyaml/components/sensor/ble_rssi.py index e209b9af64..f8856c5e89 100644 --- a/esphomeyaml/components/sensor/ble_rssi.py +++ b/esphomeyaml/components/sensor/ble_rssi.py @@ -1,11 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \ make_address_array +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME -from esphomeyaml.helpers import get_variable, esphomelib_ns +from esphomeyaml.cpp_generator import get_variable +from esphomeyaml.cpp_types import esphomelib_ns DEPENDENCIES = ['esp32_ble_tracker'] diff --git a/esphomeyaml/components/sensor/bme280.py b/esphomeyaml/components/sensor/bme280.py index 23e395f6ef..1b585a30a9 100644 --- a/esphomeyaml/components/sensor/bme280.py +++ b/esphomeyaml/components/sensor/bme280.py @@ -4,7 +4,9 @@ import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_IIR_FILTER, CONF_MAKE_ID, \ CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, add, variable, setup_component +from esphomeyaml.cpp_generator import variable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, App DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/bme680.py b/esphomeyaml/components/sensor/bme680.py index 71778574a1..3c2494df13 100644 --- a/esphomeyaml/components/sensor/bme680.py +++ b/esphomeyaml/components/sensor/bme680.py @@ -6,7 +6,9 @@ from esphomeyaml.components import sensor from esphomeyaml.const import CONF_ADDRESS, CONF_GAS_RESISTANCE, CONF_HUMIDITY, CONF_IIR_FILTER, \ CONF_MAKE_ID, CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, \ CONF_UPDATE_INTERVAL, CONF_HEATER, CONF_DURATION -from esphomeyaml.helpers import App, Application, add, variable, setup_component +from esphomeyaml.cpp_generator import variable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, App DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/bmp085.py b/esphomeyaml/components/sensor/bmp085.py index 24b7199a10..2c622a7c8f 100644 --- a/esphomeyaml/components/sensor/bmp085.py +++ b/esphomeyaml/components/sensor/bmp085.py @@ -4,7 +4,9 @@ import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_NAME, CONF_PRESSURE, \ CONF_TEMPERATURE, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, HexIntLiteral, add, variable, setup_component +from esphomeyaml.cpp_generator import variable, add, HexIntLiteral +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, App DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/bmp280.py b/esphomeyaml/components/sensor/bmp280.py index 35d30403d8..332272bab4 100644 --- a/esphomeyaml/components/sensor/bmp280.py +++ b/esphomeyaml/components/sensor/bmp280.py @@ -1,10 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_IIR_FILTER, CONF_MAKE_ID, \ CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, add, variable, setup_component +from esphomeyaml.cpp_generator import add, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/cse7766.py b/esphomeyaml/components/sensor/cse7766.py index 091c146632..8b98948236 100644 --- a/esphomeyaml/components/sensor/cse7766.py +++ b/esphomeyaml/components/sensor/cse7766.py @@ -5,7 +5,9 @@ from esphomeyaml.components.uart import UARTComponent import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_CURRENT, CONF_ID, CONF_NAME, CONF_POWER, CONF_UART_ID, \ CONF_VOLTAGE -from esphomeyaml.helpers import App, Pvariable, get_variable, setup_component, Component +from esphomeyaml.cpp_generator import Pvariable, get_variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component DEPENDENCIES = ['uart'] diff --git a/esphomeyaml/components/sensor/custom.py b/esphomeyaml/components/sensor/custom.py index 78e3f78dea..4eac07311f 100644 --- a/esphomeyaml/components/sensor/custom.py +++ b/esphomeyaml/components/sensor/custom.py @@ -3,7 +3,8 @@ import voluptuous as vol from esphomeyaml.components import sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_SENSORS -from esphomeyaml.helpers import process_lambda, std_vector, variable +from esphomeyaml.cpp_generator import process_lambda, variable +from esphomeyaml.cpp_types import std_vector CustomSensorConstructor = sensor.sensor_ns.class_('CustomSensorConstructor') diff --git a/esphomeyaml/components/sensor/dallas.py b/esphomeyaml/components/sensor/dallas.py index b974c8e636..c26917fced 100644 --- a/esphomeyaml/components/sensor/dallas.py +++ b/esphomeyaml/components/sensor/dallas.py @@ -1,11 +1,11 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor from esphomeyaml.components.dallas import DallasComponent +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_NAME, \ CONF_RESOLUTION -from esphomeyaml.helpers import HexIntLiteral, get_variable +from esphomeyaml.cpp_generator import HexIntLiteral, get_variable DallasTemperatureSensor = sensor.sensor_ns.class_('DallasTemperatureSensor', sensor.EmptyPollingParentSensor) diff --git a/esphomeyaml/components/sensor/dht.py b/esphomeyaml/components/sensor/dht.py index a13d0f0fdd..cb7f0c874e 100644 --- a/esphomeyaml/components/sensor/dht.py +++ b/esphomeyaml/components/sensor/dht.py @@ -1,12 +1,13 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor -from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_MODEL, CONF_NAME, CONF_PIN, \ - CONF_TEMPERATURE, CONF_UPDATE_INTERVAL, CONF_ID -from esphomeyaml.helpers import App, Application, add, gpio_output_pin_expression, variable, \ - setup_component, PollingComponent, Pvariable -from esphomeyaml.pins import gpio_output_pin_schema +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_MAKE_ID, CONF_MODEL, CONF_NAME, \ + CONF_PIN, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL +from esphomeyaml.cpp_generator import Pvariable, add, variable +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Application, PollingComponent +from esphomeyaml.pins import gpio_input_pullup_pin_schema DHTModel = sensor.sensor_ns.enum('DHTModel') DHT_MODELS = { @@ -27,7 +28,7 @@ DHTHumiditySensor = sensor.sensor_ns.class_('DHTHumiditySensor', PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeDHTSensor), cv.GenerateID(): cv.declare_variable_id(DHTComponent), - vol.Required(CONF_PIN): gpio_output_pin_schema, + vol.Required(CONF_PIN): gpio_input_pullup_pin_schema, vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(DHTTemperatureSensor), })), diff --git a/esphomeyaml/components/sensor/dht12.py b/esphomeyaml/components/sensor/dht12.py index 7e80ab410e..f9a97d394f 100644 --- a/esphomeyaml/components/sensor/dht12.py +++ b/esphomeyaml/components/sensor/dht12.py @@ -1,11 +1,12 @@ import voluptuous as vol +from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv -from esphomeyaml.components import sensor, i2c -from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, \ - CONF_UPDATE_INTERVAL, CONF_ID -from esphomeyaml.helpers import App, Application, variable, setup_component, PollingComponent, \ - Pvariable +from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, \ + CONF_UPDATE_INTERVAL +from esphomeyaml.cpp_generator import Pvariable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, PollingComponent DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/duty_cycle.py b/esphomeyaml/components/sensor/duty_cycle.py index 85f8ec3bd9..13f94d231f 100644 --- a/esphomeyaml/components/sensor/duty_cycle.py +++ b/esphomeyaml/components/sensor/duty_cycle.py @@ -1,11 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import sensor +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, gpio_input_pin_expression, variable, \ - setup_component +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Application MakeDutyCycleSensor = Application.struct('MakeDutyCycleSensor') DutyCycleSensor = sensor.sensor_ns.class_('DutyCycleSensor', sensor.PollingSensorComponent) diff --git a/esphomeyaml/components/sensor/esp32_hall.py b/esphomeyaml/components/sensor/esp32_hall.py index ddf2af9b5e..dbcb540024 100644 --- a/esphomeyaml/components/sensor/esp32_hall.py +++ b/esphomeyaml/components/sensor/esp32_hall.py @@ -3,7 +3,9 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL, ESP_PLATFORM_ESP32 -from esphomeyaml.helpers import App, Application, variable, setup_component +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, App ESP_PLATFORMS = [ESP_PLATFORM_ESP32] diff --git a/esphomeyaml/components/sensor/esp32_temperature.py b/esphomeyaml/components/sensor/esp32_temperature.py new file mode 100644 index 0000000000..3fc8ff0e5a --- /dev/null +++ b/esphomeyaml/components/sensor/esp32_temperature.py @@ -0,0 +1,34 @@ +import voluptuous as vol + +import esphomeyaml.config_validation as cv +from esphomeyaml.components import sensor +from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL, ESP_PLATFORM_ESP32 +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, App + +ESP_PLATFORMS = [ESP_PLATFORM_ESP32] + +MakeESP32TemperatureSensor = Application.struct('MakeESP32TemperatureSensor') +ESP32TemperatureSensor = sensor.sensor_ns.class_('ESP32TemperatureSensor', + sensor.PollingSensorComponent) + +PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(ESP32TemperatureSensor), + cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeESP32TemperatureSensor), + vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval, +}).extend(cv.COMPONENT_SCHEMA.schema)) + + +def to_code(config): + rhs = App.make_esp32_temperature_sensor(config[CONF_NAME], config.get(CONF_UPDATE_INTERVAL)) + make = variable(config[CONF_MAKE_ID], rhs) + sensor.setup_sensor(make.Phall, make.Pmqtt, config) + setup_component(make.Phall, config) + + +BUILD_FLAGS = '-DUSE_ESP32_TEMPERATURE_SENSOR' + + +def to_hass_config(data, config): + return sensor.core_to_hass_config(data, config) diff --git a/esphomeyaml/components/sensor/hdc1080.py b/esphomeyaml/components/sensor/hdc1080.py index e8decc408a..08e0c2a6d3 100644 --- a/esphomeyaml/components/sensor/hdc1080.py +++ b/esphomeyaml/components/sensor/hdc1080.py @@ -4,8 +4,9 @@ import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor, i2c from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, \ CONF_UPDATE_INTERVAL, CONF_ID -from esphomeyaml.helpers import App, Application, variable, setup_component, PollingComponent, \ - Pvariable +from esphomeyaml.cpp_generator import variable, Pvariable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, PollingComponent, App DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/hlw8012.py b/esphomeyaml/components/sensor/hlw8012.py index 0f2f7d0aa5..5c57c5ed24 100644 --- a/esphomeyaml/components/sensor/hlw8012.py +++ b/esphomeyaml/components/sensor/hlw8012.py @@ -6,8 +6,9 @@ import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_CF1_PIN, CONF_CF_PIN, CONF_CHANGE_MODE_EVERY, CONF_CURRENT, \ CONF_CURRENT_RESISTOR, CONF_ID, CONF_NAME, CONF_POWER, CONF_SEL_PIN, CONF_UPDATE_INTERVAL, \ CONF_VOLTAGE, CONF_VOLTAGE_DIVIDER -from esphomeyaml.helpers import App, PollingComponent, Pvariable, add, gpio_output_pin_expression, \ - setup_component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import PollingComponent, App HLW8012Component = sensor.sensor_ns.class_('HLW8012Component', PollingComponent) HLW8012VoltageSensor = sensor.sensor_ns.class_('HLW8012VoltageSensor', sensor.EmptySensor) diff --git a/esphomeyaml/components/sensor/hmc5883l.py b/esphomeyaml/components/sensor/hmc5883l.py index a4ed04cf0a..4bfdbca4ca 100644 --- a/esphomeyaml/components/sensor/hmc5883l.py +++ b/esphomeyaml/components/sensor/hmc5883l.py @@ -4,7 +4,9 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor, i2c from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_UPDATE_INTERVAL, CONF_RANGE -from esphomeyaml.helpers import App, Pvariable, add, setup_component, PollingComponent +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import PollingComponent, App DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/htu21d.py b/esphomeyaml/components/sensor/htu21d.py index 6c4b077d80..641cfa5ad0 100644 --- a/esphomeyaml/components/sensor/htu21d.py +++ b/esphomeyaml/components/sensor/htu21d.py @@ -4,8 +4,9 @@ from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, \ CONF_UPDATE_INTERVAL, CONF_ID -from esphomeyaml.helpers import App, Application, PollingComponent, setup_component, variable, \ - Pvariable +from esphomeyaml.cpp_generator import variable, Pvariable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, PollingComponent, App DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/hx711.py b/esphomeyaml/components/sensor/hx711.py index 9f35e31cca..3e3041182b 100644 --- a/esphomeyaml/components/sensor/hx711.py +++ b/esphomeyaml/components/sensor/hx711.py @@ -1,11 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import sensor -from esphomeyaml.const import CONF_GAIN, CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL, CONF_CLK_PIN -from esphomeyaml.helpers import App, Application, add, gpio_input_pin_expression, variable, \ - setup_component +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_CLK_PIN, CONF_GAIN, CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL +from esphomeyaml.cpp_generator import add, variable +from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Application MakeHX711Sensor = Application.struct('MakeHX711Sensor') HX711Sensor = sensor.sensor_ns.class_('HX711Sensor', sensor.PollingSensorComponent) diff --git a/esphomeyaml/components/sensor/ina219.py b/esphomeyaml/components/sensor/ina219.py index 647c099978..e03dff5323 100644 --- a/esphomeyaml/components/sensor/ina219.py +++ b/esphomeyaml/components/sensor/ina219.py @@ -6,7 +6,9 @@ import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_BUS_VOLTAGE, CONF_CURRENT, CONF_ID, \ CONF_MAX_CURRENT, CONF_MAX_VOLTAGE, CONF_NAME, CONF_POWER, CONF_SHUNT_RESISTANCE, \ CONF_SHUNT_VOLTAGE, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, PollingComponent, Pvariable, setup_component +from esphomeyaml.cpp_generator import Pvariable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, PollingComponent DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/ina3221.py b/esphomeyaml/components/sensor/ina3221.py index 0ac8dff1d7..d062ae9755 100644 --- a/esphomeyaml/components/sensor/ina3221.py +++ b/esphomeyaml/components/sensor/ina3221.py @@ -5,7 +5,9 @@ from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_BUS_VOLTAGE, CONF_CURRENT, CONF_ID, CONF_NAME, \ CONF_POWER, CONF_SHUNT_RESISTANCE, CONF_SHUNT_VOLTAGE, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, PollingComponent, Pvariable, add, setup_component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, PollingComponent DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/max6675.py b/esphomeyaml/components/sensor/max6675.py index 5bf3907ebb..821e9169bf 100644 --- a/esphomeyaml/components/sensor/max6675.py +++ b/esphomeyaml/components/sensor/max6675.py @@ -1,13 +1,14 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import sensor, spi from esphomeyaml.components.spi import SPIComponent +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_CS_PIN, CONF_MAKE_ID, CONF_NAME, CONF_SPI_ID, \ CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, get_variable, gpio_output_pin_expression, \ - variable, setup_component +from esphomeyaml.cpp_generator import get_variable, variable +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Application MakeMAX6675Sensor = Application.struct('MakeMAX6675Sensor') MAX6675Sensor = sensor.sensor_ns.class_('MAX6675Sensor', sensor.PollingSensorComponent, diff --git a/esphomeyaml/components/sensor/mhz19.py b/esphomeyaml/components/sensor/mhz19.py index 06de766952..30232deeef 100644 --- a/esphomeyaml/components/sensor/mhz19.py +++ b/esphomeyaml/components/sensor/mhz19.py @@ -5,8 +5,9 @@ from esphomeyaml.components.uart import UARTComponent import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_CO2, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, CONF_UART_ID, \ CONF_UPDATE_INTERVAL, CONF_ID -from esphomeyaml.helpers import App, Application, PollingComponent, get_variable, setup_component, \ - variable, Pvariable +from esphomeyaml.cpp_generator import get_variable, variable, Pvariable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, PollingComponent, App DEPENDENCIES = ['uart'] diff --git a/esphomeyaml/components/sensor/mpu6050.py b/esphomeyaml/components/sensor/mpu6050.py index 8fce2d8280..cd2926f5a5 100644 --- a/esphomeyaml/components/sensor/mpu6050.py +++ b/esphomeyaml/components/sensor/mpu6050.py @@ -4,7 +4,9 @@ from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \ CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, PollingComponent, Pvariable, setup_component +from esphomeyaml.cpp_generator import Pvariable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, PollingComponent DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/mqtt_subscribe.py b/esphomeyaml/components/sensor/mqtt_subscribe.py index e06cd456ae..20d5ee1fa7 100644 --- a/esphomeyaml/components/sensor/mqtt_subscribe.py +++ b/esphomeyaml/components/sensor/mqtt_subscribe.py @@ -3,7 +3,9 @@ import voluptuous as vol from esphomeyaml.components import sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_QOS, CONF_TOPIC -from esphomeyaml.helpers import App, Application, add, variable, setup_component, Component +from esphomeyaml.cpp_generator import add, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, Component DEPENDENCIES = ['mqtt'] diff --git a/esphomeyaml/components/sensor/ms5611.py b/esphomeyaml/components/sensor/ms5611.py index de176b03db..7afb60470a 100644 --- a/esphomeyaml/components/sensor/ms5611.py +++ b/esphomeyaml/components/sensor/ms5611.py @@ -4,9 +4,9 @@ from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_MAKE_ID, CONF_NAME, CONF_PRESSURE, \ CONF_TEMPERATURE, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, PollingComponent, Pvariable, add, \ - setup_component, \ - variable +from esphomeyaml.cpp_generator import Pvariable, add, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, PollingComponent DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/pmsx003.py b/esphomeyaml/components/sensor/pmsx003.py index fe4f2bc089..170da2a38f 100644 --- a/esphomeyaml/components/sensor/pmsx003.py +++ b/esphomeyaml/components/sensor/pmsx003.py @@ -5,7 +5,9 @@ from esphomeyaml.components.uart import UARTComponent import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_FORMALDEHYDE, CONF_HUMIDITY, CONF_ID, CONF_NAME, CONF_PM_10_0, \ CONF_PM_1_0, CONF_PM_2_5, CONF_TEMPERATURE, CONF_TYPE, CONF_UART_ID -from esphomeyaml.helpers import App, Pvariable, get_variable, setup_component, Component +from esphomeyaml.cpp_generator import Pvariable, get_variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component DEPENDENCIES = ['uart'] @@ -44,7 +46,6 @@ PMSX003_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(PMSX003Sensor), }) - PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(PMSX003Component), cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent), diff --git a/esphomeyaml/components/sensor/pulse_counter.py b/esphomeyaml/components/sensor/pulse_counter.py index b73d62123e..0e0843622c 100644 --- a/esphomeyaml/components/sensor/pulse_counter.py +++ b/esphomeyaml/components/sensor/pulse_counter.py @@ -1,13 +1,14 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv -from esphomeyaml import core, pins +from esphomeyaml import pins from esphomeyaml.components import sensor +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_COUNT_MODE, CONF_FALLING_EDGE, CONF_INTERNAL_FILTER, \ - CONF_MAKE_ID, CONF_NAME, CONF_PIN, CONF_PULL_MODE, CONF_RISING_EDGE, CONF_UPDATE_INTERVAL, \ - ESP_PLATFORM_ESP32 -from esphomeyaml.helpers import App, Application, add, variable, gpio_input_pin_expression, \ - setup_component + CONF_MAKE_ID, CONF_NAME, CONF_PIN, CONF_PULL_MODE, CONF_RISING_EDGE, CONF_UPDATE_INTERVAL +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import add, variable +from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Application PulseCounterCountMode = sensor.sensor_ns.enum('PulseCounterCountMode') COUNT_MODES = { @@ -26,7 +27,7 @@ PulseCounterSensorComponent = sensor.sensor_ns.class_('PulseCounterSensorCompone def validate_internal_filter(value): - if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: + if CORE.is_esp32: if isinstance(value, int): raise vol.Invalid("Please specify the internal filter in microseconds now " "(since 1.7.0). For example '17ms'") diff --git a/esphomeyaml/components/sensor/rotary_encoder.py b/esphomeyaml/components/sensor/rotary_encoder.py index 1be3d44803..c3e5b9e2fb 100644 --- a/esphomeyaml/components/sensor/rotary_encoder.py +++ b/esphomeyaml/components/sensor/rotary_encoder.py @@ -1,11 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins from esphomeyaml.components import sensor +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_RESOLUTION -from esphomeyaml.helpers import App, Application, add, gpio_input_pin_expression, variable, \ - setup_component, Component +from esphomeyaml.cpp_generator import add, variable +from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Application, Component RotaryEncoderResolution = sensor.sensor_ns.enum('RotaryEncoderResolution') RESOLUTIONS = { diff --git a/esphomeyaml/components/sensor/sht3xd.py b/esphomeyaml/components/sensor/sht3xd.py index ea6b81e75d..cd903f8f9b 100644 --- a/esphomeyaml/components/sensor/sht3xd.py +++ b/esphomeyaml/components/sensor/sht3xd.py @@ -2,10 +2,11 @@ import voluptuous as vol from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv -from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_MAKE_ID, CONF_NAME, \ - CONF_TEMPERATURE, CONF_UPDATE_INTERVAL, CONF_ID -from esphomeyaml.helpers import App, Application, PollingComponent, setup_component, variable, \ - Pvariable +from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_ID, CONF_MAKE_ID, CONF_NAME, \ + CONF_TEMPERATURE, CONF_UPDATE_INTERVAL +from esphomeyaml.cpp_generator import Pvariable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, PollingComponent DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/tcs34725.py b/esphomeyaml/components/sensor/tcs34725.py index 8322e1f054..8c5f09253c 100644 --- a/esphomeyaml/components/sensor/tcs34725.py +++ b/esphomeyaml/components/sensor/tcs34725.py @@ -5,7 +5,9 @@ from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ADDRESS, CONF_COLOR_TEMPERATURE, CONF_GAIN, CONF_ID, \ CONF_ILLUMINANCE, CONF_INTEGRATION_TIME, CONF_NAME, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, PollingComponent, Pvariable, add, setup_component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, PollingComponent DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/template.py b/esphomeyaml/components/sensor/template.py index d34f96da5d..fe0592dd69 100644 --- a/esphomeyaml/components/sensor/template.py +++ b/esphomeyaml/components/sensor/template.py @@ -1,10 +1,11 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, process_lambda, variable, Application, float_, optional, add, \ - setup_component +from esphomeyaml.cpp_generator import add, process_lambda, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, float_, optional MakeTemplateSensor = Application.struct('MakeTemplateSensor') TemplateSensor = sensor.sensor_ns.class_('TemplateSensor', sensor.PollingSensorComponent) diff --git a/esphomeyaml/components/sensor/total_daily_energy.py b/esphomeyaml/components/sensor/total_daily_energy.py index 86f4678a2b..bd2b17afd0 100644 --- a/esphomeyaml/components/sensor/total_daily_energy.py +++ b/esphomeyaml/components/sensor/total_daily_energy.py @@ -3,7 +3,9 @@ import voluptuous as vol from esphomeyaml.components import sensor, time import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_TIME_ID -from esphomeyaml.helpers import App, Application, Component, get_variable, setup_component, variable +from esphomeyaml.cpp_generator import get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import Application, Component, App DEPENDENCIES = ['time'] diff --git a/esphomeyaml/components/sensor/tsl2561.py b/esphomeyaml/components/sensor/tsl2561.py index 53112efc46..96bf11850b 100644 --- a/esphomeyaml/components/sensor/tsl2561.py +++ b/esphomeyaml/components/sensor/tsl2561.py @@ -1,10 +1,12 @@ import voluptuous as vol +from esphomeyaml.components import i2c, sensor import esphomeyaml.config_validation as cv -from esphomeyaml.components import sensor, i2c from esphomeyaml.const import CONF_ADDRESS, CONF_GAIN, CONF_INTEGRATION_TIME, CONF_MAKE_ID, \ CONF_NAME, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, add, variable, setup_component +from esphomeyaml.cpp_generator import add, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application DEPENDENCIES = ['i2c'] diff --git a/esphomeyaml/components/sensor/ultrasonic.py b/esphomeyaml/components/sensor/ultrasonic.py index d12c4419fd..b653351c02 100644 --- a/esphomeyaml/components/sensor/ultrasonic.py +++ b/esphomeyaml/components/sensor/ultrasonic.py @@ -5,8 +5,10 @@ from esphomeyaml import pins from esphomeyaml.components import sensor from esphomeyaml.const import CONF_ECHO_PIN, CONF_MAKE_ID, CONF_NAME, CONF_TIMEOUT_METER, \ CONF_TIMEOUT_TIME, CONF_TRIGGER_PIN, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, add, gpio_input_pin_expression, \ - gpio_output_pin_expression, variable, setup_component +from esphomeyaml.cpp_generator import variable, add +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, gpio_input_pin_expression, \ + setup_component +from esphomeyaml.cpp_types import Application, App MakeUltrasonicSensor = Application.struct('MakeUltrasonicSensor') UltrasonicSensorComponent = sensor.sensor_ns.class_('UltrasonicSensorComponent', diff --git a/esphomeyaml/components/sensor/uptime.py b/esphomeyaml/components/sensor/uptime.py index 60bf9a990b..561d577b4a 100644 --- a/esphomeyaml/components/sensor/uptime.py +++ b/esphomeyaml/components/sensor/uptime.py @@ -1,9 +1,11 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, variable, setup_component +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application MakeUptimeSensor = Application.struct('MakeUptimeSensor') UptimeSensor = sensor.sensor_ns.class_('UptimeSensor', sensor.PollingSensorComponent) diff --git a/esphomeyaml/components/sensor/wifi_signal.py b/esphomeyaml/components/sensor/wifi_signal.py index 564824b3aa..db44e11303 100644 --- a/esphomeyaml/components/sensor/wifi_signal.py +++ b/esphomeyaml/components/sensor/wifi_signal.py @@ -1,9 +1,11 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import sensor +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, variable, setup_component +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application MakeWiFiSignalSensor = Application.struct('MakeWiFiSignalSensor') WiFiSignalSensor = sensor.sensor_ns.class_('WiFiSignalSensor', sensor.PollingSensorComponent) diff --git a/esphomeyaml/components/sensor/xiaomi_miflora.py b/esphomeyaml/components/sensor/xiaomi_miflora.py index 6d02fe7e84..5ec566be18 100644 --- a/esphomeyaml/components/sensor/xiaomi_miflora.py +++ b/esphomeyaml/components/sensor/xiaomi_miflora.py @@ -6,7 +6,7 @@ from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLE import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_BATTERY_LEVEL, CONF_CONDUCTIVITY, CONF_ID, CONF_ILLUMINANCE, \ CONF_MAC_ADDRESS, CONF_MOISTURE, CONF_NAME, CONF_TEMPERATURE -from esphomeyaml.helpers import Pvariable, get_variable +from esphomeyaml.cpp_generator import get_variable, Pvariable DEPENDENCIES = ['esp32_ble_tracker'] diff --git a/esphomeyaml/components/sensor/xiaomi_mijia.py b/esphomeyaml/components/sensor/xiaomi_mijia.py index 10a6573d6f..675dec3a67 100644 --- a/esphomeyaml/components/sensor/xiaomi_mijia.py +++ b/esphomeyaml/components/sensor/xiaomi_mijia.py @@ -6,7 +6,7 @@ from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLE import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_BATTERY_LEVEL, CONF_HUMIDITY, CONF_MAC_ADDRESS, CONF_MAKE_ID, \ CONF_NAME, CONF_TEMPERATURE -from esphomeyaml.helpers import Pvariable, get_variable +from esphomeyaml.cpp_generator import get_variable, Pvariable DEPENDENCIES = ['esp32_ble_tracker'] diff --git a/esphomeyaml/components/spi.py b/esphomeyaml/components/spi.py index c9c98eae09..ad6fe1e69e 100644 --- a/esphomeyaml/components/spi.py +++ b/esphomeyaml/components/spi.py @@ -1,10 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_CLK_PIN, CONF_ID, CONF_MISO_PIN, CONF_MOSI_PIN -from esphomeyaml.helpers import App, Pvariable, esphomelib_ns, gpio_input_pin_expression, \ - gpio_output_pin_expression, add, setup_component, Component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import gpio_input_pin_expression, gpio_output_pin_expression, \ + setup_component +from esphomeyaml.cpp_types import App, Component, esphomelib_ns SPIComponent = esphomelib_ns.class_('SPIComponent', Component) SPIDevice = esphomelib_ns.class_('SPIDevice') diff --git a/esphomeyaml/components/status_led.py b/esphomeyaml/components/status_led.py index e67621c0ee..1fd5da1b60 100644 --- a/esphomeyaml/components/status_led.py +++ b/esphomeyaml/components/status_led.py @@ -2,8 +2,9 @@ import voluptuous as vol from esphomeyaml import config_validation as cv, pins from esphomeyaml.const import CONF_ID, CONF_PIN -from esphomeyaml.helpers import App, Pvariable, esphomelib_ns, gpio_output_pin_expression, \ - setup_component, Component +from esphomeyaml.cpp_generator import Pvariable +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Component, esphomelib_ns StatusLEDComponent = esphomelib_ns.class_('StatusLEDComponent', Component) diff --git a/esphomeyaml/components/stepper/__init__.py b/esphomeyaml/components/stepper/__init__.py index ac2ce911ac..453d0bc84a 100644 --- a/esphomeyaml/components/stepper/__init__.py +++ b/esphomeyaml/components/stepper/__init__.py @@ -4,8 +4,9 @@ from esphomeyaml.automation import ACTION_REGISTRY import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ACCELERATION, CONF_DECELERATION, CONF_ID, CONF_MAX_SPEED, \ CONF_POSITION, CONF_TARGET -from esphomeyaml.helpers import Pvariable, TemplateArguments, add, add_job, esphomelib_ns, \ - get_variable, int32, templatable, Action +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import Pvariable, TemplateArguments, add, get_variable, templatable +from esphomeyaml.cpp_types import Action, esphomelib_ns, int32 PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ @@ -78,7 +79,7 @@ def setup_stepper_core_(stepper_var, config): def setup_stepper(stepper_var, config): - add_job(setup_stepper_core_, stepper_var, config) + CORE.add_job(setup_stepper_core_, stepper_var, config) BUILD_FLAGS = '-DUSE_STEPPER' diff --git a/esphomeyaml/components/stepper/a4988.py b/esphomeyaml/components/stepper/a4988.py index 281ede1110..acdc378afe 100644 --- a/esphomeyaml/components/stepper/a4988.py +++ b/esphomeyaml/components/stepper/a4988.py @@ -4,8 +4,9 @@ from esphomeyaml import pins from esphomeyaml.components import stepper import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_DIR_PIN, CONF_ID, CONF_SLEEP_PIN, CONF_STEP_PIN -from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression, setup_component, \ - Component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import Component, App A4988 = stepper.stepper_ns.class_('A4988', stepper.Stepper, Component) diff --git a/esphomeyaml/components/switch/__init__.py b/esphomeyaml/components/switch/__init__.py index d1f36cdba8..bfdac5a2f7 100644 --- a/esphomeyaml/components/switch/__init__.py +++ b/esphomeyaml/components/switch/__init__.py @@ -2,11 +2,12 @@ import voluptuous as vol from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY from esphomeyaml.components import mqtt +from esphomeyaml.components.mqtt import setup_mqtt_component import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ICON, CONF_ID, CONF_INVERTED, CONF_MQTT_ID, CONF_INTERNAL, \ CONF_OPTIMISTIC -from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, setup_mqtt_component, \ - TemplateArguments, get_variable, Nameable, Action +from esphomeyaml.cpp_generator import add, Pvariable, TemplateArguments, get_variable +from esphomeyaml.cpp_types import esphomelib_ns, Nameable, Action, App PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ @@ -14,6 +15,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ switch_ns = esphomelib_ns.namespace('switch_') Switch = switch_ns.class_('Switch', Nameable) +SwitchPtr = Switch.operator('ptr') MQTTSwitchComponent = switch_ns.class_('MQTTSwitchComponent', mqtt.MQTTComponent) ToggleAction = switch_ns.class_('ToggleAction', Action) diff --git a/esphomeyaml/components/switch/custom.py b/esphomeyaml/components/switch/custom.py new file mode 100644 index 0000000000..00254abb81 --- /dev/null +++ b/esphomeyaml/components/switch/custom.py @@ -0,0 +1,36 @@ +import voluptuous as vol + +from esphomeyaml.components import binary_sensor, switch +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_BINARY_SENSORS, CONF_ID, CONF_LAMBDA, CONF_SWITCHES +from esphomeyaml.cpp_generator import process_lambda, variable +from esphomeyaml.cpp_types import std_vector + +CustomSwitchConstructor = switch.switch_ns.class_('CustomSwitchConstructor') + +PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(CustomSwitchConstructor), + vol.Required(CONF_LAMBDA): cv.lambda_, + vol.Required(CONF_SWITCHES): + vol.All(cv.ensure_list, [switch.SWITCH_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(switch.Switch), + })]), +}) + + +def to_code(config): + for template_ in process_lambda(config[CONF_LAMBDA], [], + return_type=std_vector.template(switch.SwitchPtr)): + yield + + rhs = CustomSwitchConstructor(template_) + custom = variable(config[CONF_ID], rhs) + for i, sens in enumerate(config[CONF_SWITCHES]): + switch.register_switch(custom.get_switch(i), sens) + + +BUILD_FLAGS = '-DUSE_CUSTOM_BINARY_SENSOR' + + +def to_hass_config(data, config): + return [binary_sensor.core_to_hass_config(data, sens) for sens in config[CONF_BINARY_SENSORS]] diff --git a/esphomeyaml/components/switch/gpio.py b/esphomeyaml/components/switch/gpio.py index 039bfcb4cb..fba4911557 100644 --- a/esphomeyaml/components/switch/gpio.py +++ b/esphomeyaml/components/switch/gpio.py @@ -4,8 +4,9 @@ from esphomeyaml import pins from esphomeyaml.components import switch import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN -from esphomeyaml.helpers import App, Application, gpio_output_pin_expression, variable, \ - setup_component, Component +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component +from esphomeyaml.cpp_types import App, Application, Component MakeGPIOSwitch = Application.struct('MakeGPIOSwitch') GPIOSwitch = switch.switch_ns.class_('GPIOSwitch', switch.Switch, Component) diff --git a/esphomeyaml/components/switch/output.py b/esphomeyaml/components/switch/output.py index 4616c2127e..79764a7fcc 100644 --- a/esphomeyaml/components/switch/output.py +++ b/esphomeyaml/components/switch/output.py @@ -3,7 +3,9 @@ import voluptuous as vol from esphomeyaml.components import output, switch import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT -from esphomeyaml.helpers import App, Application, Component, get_variable, setup_component, variable +from esphomeyaml.cpp_generator import get_variable, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, Component MakeOutputSwitch = Application.struct('MakeOutputSwitch') OutputSwitch = switch.switch_ns.class_('OutputSwitch', switch.Switch, Component) diff --git a/esphomeyaml/components/switch/remote_transmitter.py b/esphomeyaml/components/switch/remote_transmitter.py index effa4121d5..b309e4a207 100644 --- a/esphomeyaml/components/switch/remote_transmitter.py +++ b/esphomeyaml/components/switch/remote_transmitter.py @@ -12,7 +12,7 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_CHANNEL CONF_RC_SWITCH_TYPE_A, CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, \ CONF_REPEAT, CONF_SAMSUNG, CONF_SONY, CONF_STATE, CONF_TIMES, \ CONF_WAIT_TIME -from esphomeyaml.helpers import ArrayInitializer, Pvariable, add, get_variable +from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, add, get_variable DEPENDENCIES = ['remote_transmitter'] diff --git a/esphomeyaml/components/switch/restart.py b/esphomeyaml/components/switch/restart.py index c81f486dd2..f45236f896 100644 --- a/esphomeyaml/components/switch/restart.py +++ b/esphomeyaml/components/switch/restart.py @@ -1,9 +1,10 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import switch +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_INVERTED, CONF_MAKE_ID, CONF_NAME -from esphomeyaml.helpers import App, Application, variable +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_types import App, Application MakeRestartSwitch = Application.struct('MakeRestartSwitch') RestartSwitch = switch.switch_ns.class_('RestartSwitch', switch.Switch) diff --git a/esphomeyaml/components/switch/shutdown.py b/esphomeyaml/components/switch/shutdown.py index cca5f7184c..a784022544 100644 --- a/esphomeyaml/components/switch/shutdown.py +++ b/esphomeyaml/components/switch/shutdown.py @@ -3,7 +3,8 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml.components import switch from esphomeyaml.const import CONF_INVERTED, CONF_MAKE_ID, CONF_NAME -from esphomeyaml.helpers import App, Application, variable +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_types import Application, App MakeShutdownSwitch = Application.struct('MakeShutdownSwitch') ShutdownSwitch = switch.switch_ns.class_('ShutdownSwitch', switch.Switch) diff --git a/esphomeyaml/components/switch/template.py b/esphomeyaml/components/switch/template.py index 464d90feb7..f1dd46dcfa 100644 --- a/esphomeyaml/components/switch/template.py +++ b/esphomeyaml/components/switch/template.py @@ -1,12 +1,13 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import automation from esphomeyaml.components import switch -from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_TURN_OFF_ACTION, \ - CONF_TURN_ON_ACTION, CONF_OPTIMISTIC, CONF_RESTORE_STATE -from esphomeyaml.helpers import App, Application, process_lambda, variable, NoArg, add, bool_, \ - optional, setup_component, Component +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_OPTIMISTIC, \ + CONF_RESTORE_STATE, CONF_TURN_OFF_ACTION, CONF_TURN_ON_ACTION +from esphomeyaml.cpp_generator import add, process_lambda, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, Component, NoArg, bool_, optional MakeTemplateSwitch = Application.struct('MakeTemplateSwitch') TemplateSwitch = switch.switch_ns.class_('TemplateSwitch', switch.Switch, Component) diff --git a/esphomeyaml/components/switch/uart.py b/esphomeyaml/components/switch/uart.py index 3cbe26dc36..c0747a0c9b 100644 --- a/esphomeyaml/components/switch/uart.py +++ b/esphomeyaml/components/switch/uart.py @@ -1,11 +1,12 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml.components import switch, uart from esphomeyaml.components.uart import UARTComponent +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_DATA, CONF_INVERTED, CONF_MAKE_ID, CONF_NAME, CONF_UART_ID from esphomeyaml.core import HexInt -from esphomeyaml.helpers import App, Application, ArrayInitializer, get_variable, variable +from esphomeyaml.cpp_generator import ArrayInitializer, get_variable, variable +from esphomeyaml.cpp_types import App, Application DEPENDENCIES = ['uart'] diff --git a/esphomeyaml/components/text_sensor/__init__.py b/esphomeyaml/components/text_sensor/__init__.py index 0348b07fed..91b56177df 100644 --- a/esphomeyaml/components/text_sensor/__init__.py +++ b/esphomeyaml/components/text_sensor/__init__.py @@ -2,11 +2,13 @@ import voluptuous as vol from esphomeyaml import automation from esphomeyaml.components import mqtt +from esphomeyaml.components.mqtt import setup_mqtt_component import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_ICON, CONF_ID, CONF_INTERNAL, CONF_MQTT_ID, CONF_ON_VALUE, \ CONF_TRIGGER_ID -from esphomeyaml.helpers import App, Pvariable, add, add_job, esphomelib_ns, setup_mqtt_component, \ - std_string, Nameable, Trigger +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_types import esphomelib_ns, Nameable, Trigger, std_string, App PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ @@ -15,6 +17,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ # pylint: disable=invalid-name text_sensor_ns = esphomelib_ns.namespace('text_sensor') TextSensor = text_sensor_ns.class_('TextSensor', Nameable) +TextSensorPtr = TextSensor.operator('ptr') MQTTTextSensor = text_sensor_ns.class_('MQTTTextSensor', mqtt.MQTTComponent) TextSensorStateTrigger = text_sensor_ns.class_('TextSensorStateTrigger', @@ -48,14 +51,14 @@ def setup_text_sensor_core_(text_sensor_var, mqtt_var, config): def setup_text_sensor(text_sensor_obj, mqtt_obj, config): sensor_var = Pvariable(config[CONF_ID], text_sensor_obj, has_side_effects=False) mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) - add_job(setup_text_sensor_core_, sensor_var, mqtt_var, config) + CORE.add_job(setup_text_sensor_core_, sensor_var, mqtt_var, config) def register_text_sensor(var, config): text_sensor_var = Pvariable(config[CONF_ID], var, has_side_effects=True) rhs = App.register_text_sensor(text_sensor_var) mqtt_var = Pvariable(config[CONF_MQTT_ID], rhs, has_side_effects=True) - add_job(setup_text_sensor_core_, text_sensor_var, mqtt_var, config) + CORE.add_job(setup_text_sensor_core_, text_sensor_var, mqtt_var, config) BUILD_FLAGS = '-DUSE_TEXT_SENSOR' diff --git a/esphomeyaml/components/text_sensor/custom.py b/esphomeyaml/components/text_sensor/custom.py new file mode 100644 index 0000000000..f12b3d1672 --- /dev/null +++ b/esphomeyaml/components/text_sensor/custom.py @@ -0,0 +1,36 @@ +import voluptuous as vol + +from esphomeyaml.components import text_sensor +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_TEXT_SENSORS +from esphomeyaml.cpp_generator import process_lambda, variable +from esphomeyaml.cpp_types import std_vector + +CustomTextSensorConstructor = text_sensor.text_sensor_ns.class_('CustomTextSensorConstructor') + +PLATFORM_SCHEMA = text_sensor.PLATFORM_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(CustomTextSensorConstructor), + vol.Required(CONF_LAMBDA): cv.lambda_, + vol.Required(CONF_TEXT_SENSORS): + vol.All(cv.ensure_list, [text_sensor.TEXT_SENSOR_SCHEMA.extend({ + cv.GenerateID(): cv.declare_variable_id(text_sensor.TextSensor), + })]), +}) + + +def to_code(config): + for template_ in process_lambda(config[CONF_LAMBDA], [], + return_type=std_vector.template(text_sensor.TextSensorPtr)): + yield + + rhs = CustomTextSensorConstructor(template_) + custom = variable(config[CONF_ID], rhs) + for i, sens in enumerate(config[CONF_TEXT_SENSORS]): + text_sensor.register_text_sensor(custom.get_text_sensor(i), sens) + + +BUILD_FLAGS = '-DUSE_CUSTOM_TEXT_SENSOR' + + +def to_hass_config(data, config): + return [text_sensor.core_to_hass_config(data, sens) for sens in config[CONF_TEXT_SENSORS]] diff --git a/esphomeyaml/components/text_sensor/mqtt_subscribe.py b/esphomeyaml/components/text_sensor/mqtt_subscribe.py index c4dafadee7..826b03ebdf 100644 --- a/esphomeyaml/components/text_sensor/mqtt_subscribe.py +++ b/esphomeyaml/components/text_sensor/mqtt_subscribe.py @@ -3,7 +3,9 @@ import voluptuous as vol from esphomeyaml.components import text_sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_QOS, CONF_TOPIC -from esphomeyaml.helpers import App, Application, add, variable, setup_component, Component +from esphomeyaml.cpp_generator import add, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, Component DEPENDENCIES = ['mqtt'] diff --git a/esphomeyaml/components/text_sensor/template.py b/esphomeyaml/components/text_sensor/template.py index 264841ea4b..b482af2135 100644 --- a/esphomeyaml/components/text_sensor/template.py +++ b/esphomeyaml/components/text_sensor/template.py @@ -3,8 +3,9 @@ import voluptuous as vol from esphomeyaml.components import text_sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL -from esphomeyaml.helpers import App, Application, add, optional, process_lambda, std_string, \ - variable, setup_component, PollingComponent +from esphomeyaml.cpp_generator import add, process_lambda, variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, PollingComponent, optional, std_string MakeTemplateTextSensor = Application.struct('MakeTemplateTextSensor') TemplateTextSensor = text_sensor.text_sensor_ns.class_('TemplateTextSensor', diff --git a/esphomeyaml/components/text_sensor/version.py b/esphomeyaml/components/text_sensor/version.py index 1bfbac7fe6..6c64575dd4 100644 --- a/esphomeyaml/components/text_sensor/version.py +++ b/esphomeyaml/components/text_sensor/version.py @@ -1,7 +1,9 @@ from esphomeyaml.components import text_sensor import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME -from esphomeyaml.helpers import App, Application, variable, setup_component, Component +from esphomeyaml.cpp_generator import variable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Application, Component MakeVersionTextSensor = Application.struct('MakeVersionTextSensor') VersionTextSensor = text_sensor.text_sensor_ns.class_('VersionTextSensor', diff --git a/esphomeyaml/components/time/__init__.py b/esphomeyaml/components/time/__init__.py index 30a4f5e7d7..9e27c15b11 100644 --- a/esphomeyaml/components/time/__init__.py +++ b/esphomeyaml/components/time/__init__.py @@ -8,8 +8,9 @@ import esphomeyaml.config_validation as cv from esphomeyaml import automation from esphomeyaml.const import CONF_CRON, CONF_DAYS_OF_MONTH, CONF_DAYS_OF_WEEK, CONF_HOURS, \ CONF_MINUTES, CONF_MONTHS, CONF_ON_TIME, CONF_SECONDS, CONF_TIMEZONE, CONF_TRIGGER_ID -from esphomeyaml.helpers import App, NoArg, Pvariable, add, add_job, esphomelib_ns, \ - ArrayInitializer, Component, Trigger +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import add, Pvariable, ArrayInitializer +from esphomeyaml.cpp_types import esphomelib_ns, Component, NoArg, Trigger, App _LOGGER = logging.getLogger(__name__) @@ -297,7 +298,7 @@ def setup_time_core_(time_var, config): def setup_time(time_var, config): - add_job(setup_time_core_, time_var, config) + CORE.add_job(setup_time_core_, time_var, config) BUILD_FLAGS = '-DUSE_TIME' diff --git a/esphomeyaml/components/time/sntp.py b/esphomeyaml/components/time/sntp.py index 0422c8b6fa..5adc21ad85 100644 --- a/esphomeyaml/components/time/sntp.py +++ b/esphomeyaml/components/time/sntp.py @@ -3,7 +3,9 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml.components import time as time_ from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_SERVERS -from esphomeyaml.helpers import App, Pvariable, add, setup_component +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App SNTPComponent = time_.time_ns.class_('SNTPComponent', time_.RealTimeClockComponent) diff --git a/esphomeyaml/components/uart.py b/esphomeyaml/components/uart.py index 8f5b9463fb..cdb2581d6b 100644 --- a/esphomeyaml/components/uart.py +++ b/esphomeyaml/components/uart.py @@ -1,9 +1,11 @@ import voluptuous as vol -import esphomeyaml.config_validation as cv from esphomeyaml import pins +import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_RX_PIN, CONF_TX_PIN -from esphomeyaml.helpers import App, Pvariable, esphomelib_ns, setup_component, Component +from esphomeyaml.cpp_generator import Pvariable +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import App, Component, esphomelib_ns UARTComponent = esphomelib_ns.class_('UARTComponent', Component) UARTDevice = esphomelib_ns.class_('UARTDevice') diff --git a/esphomeyaml/components/web_server.py b/esphomeyaml/components/web_server.py index 8a3a06436d..fb263a8cbc 100644 --- a/esphomeyaml/components/web_server.py +++ b/esphomeyaml/components/web_server.py @@ -1,10 +1,11 @@ import voluptuous as vol -from esphomeyaml import core import esphomeyaml.config_validation as cv -from esphomeyaml.const import CONF_CSS_URL, CONF_ID, CONF_JS_URL, CONF_PORT, ESP_PLATFORM_ESP32 -from esphomeyaml.helpers import App, Component, Pvariable, StoringController, add, esphomelib_ns, \ - setup_component +from esphomeyaml.const import CONF_CSS_URL, CONF_ID, CONF_JS_URL, CONF_PORT +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import Pvariable, add +from esphomeyaml.cpp_helpers import setup_component +from esphomeyaml.cpp_types import esphomelib_ns, StoringController, Component, App WebServer = esphomelib_ns.class_('WebServer', Component, StoringController) @@ -31,6 +32,6 @@ BUILD_FLAGS = '-DUSE_WEB_SERVER' def lib_deps(config): - if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: + if CORE.is_esp32: return 'FS' return '' diff --git a/esphomeyaml/components/wifi.py b/esphomeyaml/components/wifi.py index a627f9bb73..34947f71c6 100644 --- a/esphomeyaml/components/wifi.py +++ b/esphomeyaml/components/wifi.py @@ -1,12 +1,12 @@ import voluptuous as vol -from esphomeyaml import core import esphomeyaml.config_validation as cv from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_DOMAIN, \ - CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_POWER_SAVE_MODE,\ - CONF_REBOOT_TIMEOUT, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, ESP_PLATFORM_ESP8266 -from esphomeyaml.helpers import App, Pvariable, StructInitializer, add, esphomelib_ns, global_ns, \ - Component + CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_POWER_SAVE_MODE, \ + CONF_REBOOT_TIMEOUT, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET +from esphomeyaml.core import CORE +from esphomeyaml.cpp_generator import Pvariable, StructInitializer, add +from esphomeyaml.cpp_types import App, Component, esphomelib_ns, global_ns def validate_password(value): @@ -140,6 +140,6 @@ def to_code(config): def lib_deps(config): - if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: + if CORE.is_esp8266: return 'ESP8266WiFi' return None diff --git a/esphomeyaml/config.py b/esphomeyaml/config.py index 9aaefbe860..9c47603c52 100644 --- a/esphomeyaml/config.py +++ b/esphomeyaml/config.py @@ -1,16 +1,16 @@ from __future__ import print_function +from collections import OrderedDict import importlib import logging -from collections import OrderedDict import voluptuous as vol from voluptuous.humanize import humanize_error -from esphomeyaml import core, yaml_util, core_config +from esphomeyaml import core, core_config, yaml_util from esphomeyaml.const import CONF_ESPHOMEYAML, CONF_PLATFORM, CONF_WIFI, ESP_PLATFORMS -from esphomeyaml.core import ESPHomeYAMLError -from esphomeyaml.helpers import color, MockObjClass +from esphomeyaml.core import CORE, EsphomeyamlError +from esphomeyaml.helpers import color from esphomeyaml.util import safe_print _LOGGER = logging.getLogger(__name__) @@ -50,6 +50,7 @@ def is_platform_component(component): def iter_components(config): for domain, conf in config.iteritems(): if domain == CONF_ESPHOMEYAML: + yield CONF_ESPHOMEYAML, core_config, conf continue component = get_component(domain) yield domain, component, conf @@ -90,6 +91,8 @@ def iter_ids(config, prefix=None, parent=None): def do_id_pass(result): + from esphomeyaml.cpp_generator import MockObjClass + declare_ids = [] searching_ids = [] for id, prefix, config in iter_ids(result): @@ -138,7 +141,7 @@ def validate_config(config): for req in REQUIRED_COMPONENTS: if req not in config: - raise ESPHomeYAMLError("Component {} is required for esphomeyaml.".format(req)) + raise EsphomeyamlError("Component {} is required for esphomeyaml.".format(req)) _ALL_COMPONENTS = list(config.keys()) @@ -193,8 +196,8 @@ def validate_config(config): continue esp_platforms = getattr(component, 'ESP_PLATFORMS', ESP_PLATFORMS) - if core.ESP_PLATFORM not in esp_platforms: - result.add_error(u"Component {} doesn't support {}.".format(domain, core.ESP_PLATFORM), + if CORE.esp_platform not in esp_platforms: + result.add_error(u"Component {} doesn't support {}.".format(domain, CORE.esp_platform), domain, conf) continue @@ -243,9 +246,9 @@ def validate_config(config): continue esp_platforms = getattr(platform, 'ESP_PLATFORMS', ESP_PLATFORMS) - if core.ESP_PLATFORM not in esp_platforms: + if CORE.esp_platform not in esp_platforms: result.add_error( - u"Platform {} doesn't support {}.".format(p_domain, core.ESP_PLATFORM), + u"Platform {} doesn't support {}.".format(p_domain, CORE.esp_platform), p_domain, p_config) continue @@ -285,17 +288,17 @@ def _format_config_error(ex, domain, config): return message -def load_config(path): +def load_config(): try: - config = yaml_util.load_yaml(path) + config = yaml_util.load_yaml(CORE.config_path) except OSError: - raise ESPHomeYAMLError(u"Could not read configuration file at {}".format(path)) - core.RAW_CONFIG = config + raise EsphomeyamlError(u"Could not read configuration file at {}".format(CORE.config_path)) + CORE.raw_config = config core_config.preload_core_config(config) try: result = validate_config(config) - except ESPHomeYAMLError: + except EsphomeyamlError: raise except Exception: _LOGGER.error(u"Unexpected exception while reading configuration:") @@ -338,11 +341,11 @@ def dump_dict(layer, indent_count=3, listi=False, **kwargs): safe_print(u" {} {}".format(indent_str, i)) -def read_config(path): +def read_config(): _LOGGER.info("Reading configuration...") try: - res = load_config(path) - except ESPHomeYAMLError as err: + res = load_config() + except EsphomeyamlError as err: _LOGGER.error(u"Error while reading config: %s", err) return None excepts = {} diff --git a/esphomeyaml/config_validation.py b/esphomeyaml/config_validation.py index dac218c76b..b8eb7e2f68 100644 --- a/esphomeyaml/config_validation.py +++ b/esphomeyaml/config_validation.py @@ -9,12 +9,12 @@ import uuid as uuid_ import voluptuous as vol -from esphomeyaml import core, helpers +from esphomeyaml import core from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_ID, \ - CONF_NAME, CONF_PAYLOAD_AVAILABLE, \ - CONF_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC, \ - ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_INTERNAL, CONF_SETUP_PRIORITY -from esphomeyaml.core import HexInt, IPAddress, Lambda, TimePeriod, TimePeriodMicroseconds, \ + CONF_INTERNAL, CONF_NAME, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, \ + CONF_RETAIN, CONF_SETUP_PRIORITY, CONF_STATE_TOPIC, CONF_TOPIC, ESP_PLATFORM_ESP32, \ + ESP_PLATFORM_ESP8266 +from esphomeyaml.core import CORE, HexInt, IPAddress, Lambda, TimePeriod, TimePeriodMicroseconds, \ TimePeriodMilliseconds, TimePeriodSeconds _LOGGER = logging.getLogger(__name__) @@ -198,7 +198,7 @@ def only_on(platforms): platforms = [platforms] def validator_(obj): - if core.ESP_PLATFORM not in platforms: + if CORE.esp_platform not in platforms: raise vol.Invalid(u"This feature is only available on {}".format(platforms)) return obj @@ -621,7 +621,7 @@ def dimensions(value): def directory(value): value = string(value) - path = helpers.relative_path(value) + path = CORE.relative_path(value) if not os.path.exists(path): raise vol.Invalid(u"Could not find directory '{}'. Please make sure it exists.".format( path)) @@ -632,7 +632,7 @@ def directory(value): def file_(value): value = string(value) - path = helpers.relative_path(value) + path = CORE.relative_path(value) if not os.path.exists(path): raise vol.Invalid(u"Could not find file '{}'. Please make sure it exists.".format( path)) diff --git a/esphomeyaml/const.py b/esphomeyaml/const.py index 74a6fa5e3a..a769a128da 100644 --- a/esphomeyaml/const.py +++ b/esphomeyaml/const.py @@ -372,7 +372,12 @@ CONF_INITIAL_VALUE = 'initial_value' CONF_RESTORE_VALUE = 'restore_value' CONF_PINS = 'pins' CONF_SENSORS = 'sensors' - +CONF_BINARY_SENSORS = 'binary_sensors' +CONF_OUTPUTS = 'outputs' +CONF_SWITCHES = 'switches' +CONF_TEXT_SENSORS = 'text_sensors' +CONF_INCLUDES = 'includes' +CONF_EXTRA_LIBRARIES = 'extra_libraries' ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyz0123456789_' ARDUINO_VERSION_ESP32_DEV = 'https://github.com/platformio/platform-espressif32.git#feature/stage' diff --git a/esphomeyaml/core.py b/esphomeyaml/core.py index e59159471a..ec9f9f9e42 100644 --- a/esphomeyaml/core.py +++ b/esphomeyaml/core.py @@ -1,9 +1,22 @@ -import math -import re +import collections from collections import OrderedDict +import inspect +import logging +import math +import os +import re + +from typing import Any, Dict, List + +from esphomeyaml.const import CONF_ARDUINO_VERSION, CONF_DOMAIN, CONF_ESPHOMELIB_VERSION, \ + CONF_ESPHOMEYAML, CONF_HOSTNAME, CONF_LOCAL, CONF_MANUAL_IP, CONF_STATIC_IP, CONF_WIFI, \ + ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 +from esphomeyaml.helpers import ensure_unique_string + +_LOGGER = logging.getLogger(__name__) -class ESPHomeYAMLError(Exception): +class EsphomeyamlError(Exception): """General esphomeyaml exception occurred.""" pass @@ -35,10 +48,10 @@ class MACAddress(object): return ':'.join('{:02X}'.format(part) for part in self.parts) def as_hex(self): - import esphomeyaml.helpers + from esphomeyaml.cpp_generator import RawExpression num = ''.join('{:02X}'.format(part) for part in self.parts) - return esphomeyaml.helpers.RawExpression('0x{}ULL'.format(num)) + return RawExpression('0x{}ULL'.format(num)) def is_approximately_integer(value): @@ -208,19 +221,6 @@ class Lambda(object): 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 @@ -253,8 +253,146 @@ class ID(object): return hash(self.id) -CONFIG_PATH = None -ESP_PLATFORM = '' -BOARD = '' -RAW_CONFIG = None -NAME = '' +class EsphomeyamlCore(object): + def __init__(self): + # The name of the node + self.name = None # type: str + # The relative path to the configuration YAML + self.config_path = None # type: str + # The relative path to where all build files are stored + self.build_path = None # type: str + # The platform (ESP8266, ESP32) of this device + self.esp_platform = None # type: str + # The board that's used (for example nodemcuv2) + self.board = None # type: str + # The full raw configuration + self.raw_config = None # type: ConfigType + # The validated configuration, this is None until the config has been validated + self.config = None # type: ConfigType + # The pending tasks in the task queue (mostly for C++ generation) + self.pending_tasks = collections.deque() + # The variable cache, for each ID this holds a MockObj of the variable obj + self.variables = {} # type: Dict[str, MockObj] + # The list of expressions for the C++ generation + self.expressions = [] # type: List[Expression] + + @property + def address(self): # type: () -> str + if CONF_MANUAL_IP in self.config[CONF_WIFI]: + return str(self.config[CONF_WIFI][CONF_MANUAL_IP][CONF_STATIC_IP]) + elif CONF_HOSTNAME in self.config[CONF_WIFI]: + hostname = self.config[CONF_WIFI][CONF_HOSTNAME] + else: + hostname = self.name + return hostname + self.config[CONF_WIFI][CONF_DOMAIN] + + @property + def esphomelib_version(self): # type: () -> Dict[str, str] + return self.config[CONF_ESPHOMEYAML][CONF_ESPHOMELIB_VERSION] + + @property + def is_local_esphomelib_copy(self): + return CONF_LOCAL in self.esphomelib_version + + @property + def arduino_version(self): # type: () -> str + return self.config[CONF_ESPHOMEYAML][CONF_ARDUINO_VERSION] + + @property + def config_dir(self): + return os.path.dirname(self.config_path) + + @property + def config_filename(self): + return os.path.basename(self.config_path) + + def relative_path(self, *path): + path_ = os.path.expanduser(os.path.join(*path)) + return os.path.join(self.config_dir, path_) + + def relative_build_path(self, *path): + path_ = os.path.expanduser(os.path.join(*path)) + return os.path.join(self.build_path, path_) + + @property + def firmware_bin(self): + return self.relative_build_path('.pioenvs', self.name, 'firmware.bin') + + @property + def is_esp8266(self): + if self.esp_platform is None: + raise ValueError + return self.esp_platform == ESP_PLATFORM_ESP8266 + + @property + def is_esp32(self): + if self.esp_platform is None: + raise ValueError + return self.esp_platform == ESP_PLATFORM_ESP32 + + def add_job(self, func, *args, **kwargs): + domain = kwargs.get('domain') + if inspect.isgeneratorfunction(func): + def func_(): + yield + for _ in func(*args): + yield + else: + def func_(): + yield + func(*args) + gen = func_() + self.pending_tasks.append((gen, domain)) + return gen + + def flush_tasks(self): + i = 0 + while self.pending_tasks: + i += 1 + if i > 1000000: + raise EsphomeyamlError("Circular dependency detected!") + + task, domain = self.pending_tasks.popleft() + _LOGGER.debug("Executing task for domain=%s", domain) + try: + task.next() + self.pending_tasks.append((task, domain)) + except StopIteration: + _LOGGER.debug(" -> %s finished", domain) + + def add(self, expression, require=True): + from esphomeyaml.cpp_generator import Expression + + if require and isinstance(expression, Expression): + expression.require() + self.expressions.append(expression) + _LOGGER.debug("Adding: %s", expression) + return expression + + def get_variable(self, id): + while True: + if id in self.variables: + yield self.variables[id] + return + _LOGGER.debug("Waiting for variable %s", id) + yield None + + def get_variable_with_full_id(self, id): + while True: + if id in self.variables: + for k, v in self.variables.iteritems(): + if k == id: + yield (k, v) + return + _LOGGER.debug("Waiting for variable %s", id) + yield None, None + + def register_variable(self, id, obj): + _LOGGER.debug("Registered variable %s of type %s", id.id, id.type) + self.variables[id] = obj + + +CORE = EsphomeyamlCore() + +ConfigType = Dict[str, Any] +CoreType = EsphomeyamlCore diff --git a/esphomeyaml/core_config.py b/esphomeyaml/core_config.py index cbeea9e486..6b815fbab9 100644 --- a/esphomeyaml/core_config.py +++ b/esphomeyaml/core_config.py @@ -1,22 +1,21 @@ +import codecs import logging import os import re -import subprocess import voluptuous as vol -from esphomeyaml import automation, core, pins +from esphomeyaml import automation, pins import esphomeyaml.config_validation as cv from esphomeyaml.const import ARDUINO_VERSION_ESP32_DEV, ARDUINO_VERSION_ESP8266_DEV, \ CONF_ARDUINO_VERSION, CONF_BOARD, CONF_BOARD_FLASH_MODE, CONF_BRANCH, CONF_BUILD_PATH, \ CONF_COMMIT, CONF_ESPHOMELIB_VERSION, CONF_ESPHOMEYAML, CONF_LOCAL, CONF_NAME, CONF_ON_BOOT, \ CONF_ON_LOOP, CONF_ON_SHUTDOWN, CONF_PLATFORM, CONF_PRIORITY, CONF_REPOSITORY, CONF_TAG, \ CONF_TRIGGER_ID, CONF_USE_CUSTOM_CODE, ESPHOMELIB_VERSION, ESP_PLATFORM_ESP32, \ - ESP_PLATFORM_ESP8266 -from esphomeyaml.core import ESPHomeYAMLError -from esphomeyaml.helpers import App, NoArg, Pvariable, RawExpression, add, const_char_p, \ - esphomelib_ns, relative_path -from esphomeyaml.util import safe_print + ESP_PLATFORM_ESP8266, CONF_EXTRA_LIBRARIES, CONF_INCLUDES +from esphomeyaml.core import CORE, EsphomeyamlError +from esphomeyaml.cpp_generator import Pvariable, RawExpression, add +from esphomeyaml.cpp_types import App, NoArg, const_char_ptr, esphomelib_ns _LOGGER = logging.getLogger(__name__) @@ -27,13 +26,13 @@ StartupTrigger = esphomelib_ns.StartupTrigger ShutdownTrigger = esphomelib_ns.ShutdownTrigger LoopTrigger = esphomelib_ns.LoopTrigger -VERSION_REGEX = re.compile(r'^[0-9]+\.[0-9]+\.[0-9]+(?:-beta)?(?:-alpha)?$') +VERSION_REGEX = re.compile(r'^[0-9]+\.[0-9]+\.[0-9]+(?:[ab]\d+)?$') def validate_board(value): - if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: + if CORE.is_esp8266: board_pins = pins.ESP8266_BOARD_PINS - elif core.ESP_PLATFORM == ESP_PLATFORM_ESP32: + elif CORE.is_esp32: board_pins = pins.ESP32_BOARD_PINS else: raise NotImplementedError @@ -68,7 +67,7 @@ def validate_simple_esphomelib_version(value): def validate_local_esphomelib_version(value): value = cv.directory(value) - path = relative_path(value) + path = CORE.relative_path(value) library_json = os.path.join(path, 'library.json') if not os.path.exists(library_json): raise vol.Invalid(u"Could not find '{}' file. '{}' does not seem to point to an " @@ -132,7 +131,7 @@ PLATFORMIO_ESP32_LUT = { def validate_arduino_version(value): value = cv.string_strict(value) value_ = value.upper() - if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: + if CORE.is_esp8266: if VERSION_REGEX.match(value) is not None and value_ not in PLATFORMIO_ESP8266_LUT: raise vol.Invalid("Unfortunately the arduino framework version '{}' is unsupported " "at this time. You can override this by manually using " @@ -140,7 +139,7 @@ def validate_arduino_version(value): if value_ in PLATFORMIO_ESP8266_LUT: return PLATFORMIO_ESP8266_LUT[value_] return value - elif core.ESP_PLATFORM == ESP_PLATFORM_ESP32: + elif CORE.is_esp32: if VERSION_REGEX.match(value) is not None and value_ not in PLATFORMIO_ESP32_LUT: raise vol.Invalid("Unfortunately the arduino framework version '{}' is unsupported " "at this time. You can override this by manually using " @@ -148,12 +147,11 @@ def validate_arduino_version(value): if value_ in PLATFORMIO_ESP32_LUT: return PLATFORMIO_ESP32_LUT[value_] return value - else: - raise NotImplementedError + raise NotImplementedError def default_build_path(): - return core.NAME + return CORE.name CONFIG_SCHEMA = vol.Schema({ @@ -177,6 +175,8 @@ CONFIG_SCHEMA = vol.Schema({ vol.Optional(CONF_ON_LOOP): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(LoopTrigger), }), + vol.Optional(CONF_INCLUDES): vol.All(cv.ensure_list, [cv.file_]), + vol.Optional(CONF_EXTRA_LIBRARIES): vol.All(cv.ensure_list, [cv.string_strict]), vol.Optional('library_uri'): cv.invalid("The library_uri option has been removed in 1.8.0 and " "was moved into the esphomelib_version option."), @@ -187,59 +187,23 @@ CONFIG_SCHEMA = vol.Schema({ def preload_core_config(config): if CONF_ESPHOMEYAML not in config: - raise ESPHomeYAMLError(u"No esphomeyaml section in config") + raise EsphomeyamlError(u"No esphomeyaml section in config") core_conf = config[CONF_ESPHOMEYAML] if CONF_PLATFORM not in core_conf: - raise ESPHomeYAMLError("esphomeyaml.platform not specified.") + raise EsphomeyamlError("esphomeyaml.platform not specified.") if CONF_BOARD not in core_conf: - raise ESPHomeYAMLError("esphomeyaml.board not specified.") + raise EsphomeyamlError("esphomeyaml.board not specified.") if CONF_NAME not in core_conf: - raise ESPHomeYAMLError("esphomeyaml.name not specified.") + raise EsphomeyamlError("esphomeyaml.name not specified.") try: - core.ESP_PLATFORM = validate_platform(core_conf[CONF_PLATFORM]) - core.BOARD = validate_board(core_conf[CONF_BOARD]) - core.NAME = cv.valid_name(core_conf[CONF_NAME]) + CORE.esp_platform = validate_platform(core_conf[CONF_PLATFORM]) + CORE.board = validate_board(core_conf[CONF_BOARD]) + CORE.name = cv.valid_name(core_conf[CONF_NAME]) + CORE.build_path = CORE.relative_path( + cv.string(core_conf.get(CONF_BUILD_PATH, default_build_path()))) except vol.Invalid as e: - raise ESPHomeYAMLError(unicode(e)) - - -def run_command(*args): - p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - rc = p.returncode - return rc, stdout, stderr - - -def update_esphomelib_repo(config): - esphomelib_version = config[CONF_ESPHOMELIB_VERSION] - if CONF_REPOSITORY not in esphomelib_version: - return - - build_path = relative_path(config[CONF_BUILD_PATH]) - esphomelib_path = os.path.join(build_path, '.piolibdeps', 'esphomelib') - is_default_branch = all(x not in esphomelib_version - for x in (CONF_BRANCH, CONF_TAG, CONF_COMMIT)) - if not (CONF_BRANCH in esphomelib_version or is_default_branch): - # Git commit hash or tag cannot be updated - return - - rc, _, _ = run_command('git', '-C', esphomelib_path, '--help') - if rc != 0: - # git not installed or repo not downloaded yet - return - rc, _, _ = run_command('git', '-C', esphomelib_path, 'diff-index', '--quiet', 'HEAD', '--') - if rc != 0: - # local changes, cannot update - _LOGGER.warn("Local changes in esphomelib copy from git. Will not auto-update.") - return - _LOGGER.info("Updating esphomelib copy from git (%s)", esphomelib_path) - rc, stdout, _ = run_command('git', '-c', 'color.ui=always', '-C', esphomelib_path, - 'pull', '--stat') - if rc != 0: - _LOGGER.warn("Couldn't auto-update local git copy of esphomelib.") - return - safe_print(stdout.strip()) + raise EsphomeyamlError(unicode(e)) def to_code(config): @@ -252,13 +216,23 @@ def to_code(config): for conf in config.get(CONF_ON_SHUTDOWN, []): trigger = Pvariable(conf[CONF_TRIGGER_ID], ShutdownTrigger.new()) - automation.build_automation(trigger, const_char_p, conf) + automation.build_automation(trigger, const_char_ptr, conf) for conf in config.get(CONF_ON_LOOP, []): rhs = App.register_component(LoopTrigger.new()) trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) automation.build_automation(trigger, NoArg, conf) - update_esphomelib_repo(config) - add(App.set_compilation_datetime(RawExpression('__DATE__ ", " __TIME__'))) + + +def lib_deps(config): + return set(config.get(CONF_EXTRA_LIBRARIES, [])) + + +def includes(config): + ret = [] + for include in config.get(CONF_INCLUDES, []): + with codecs.open(CORE.relative_path(include), 'r', encoding='utf-8') as f_handle: + ret.append(f_handle.read()) + return ret diff --git a/esphomeyaml/cpp_generator.py b/esphomeyaml/cpp_generator.py new file mode 100644 index 0000000000..6ae4a52d67 --- /dev/null +++ b/esphomeyaml/cpp_generator.py @@ -0,0 +1,535 @@ +from collections import OrderedDict + +from typing import Any, Generator, List, Optional, Tuple, Union + +from esphomeyaml.core import CORE, HexInt, ID, Lambda, TimePeriod, TimePeriodMicroseconds, \ + TimePeriodMilliseconds, TimePeriodSeconds +from esphomeyaml.helpers import cpp_string_escape, indent_all_but_first_and_last + + +class Expression(object): + def __init__(self): + self.requires = [] + self.required = False + + def __str__(self): + raise NotImplementedError + + def require(self): + self.required = True + for require in self.requires: + if require.required: + continue + require.require() + + def has_side_effects(self): + return self.required + + +SafeExpType = Union[Expression, bool, str, unicode, int, long, float, TimePeriod] + + +class RawExpression(Expression): + def __init__(self, text): # type: (Union[str, unicode]) -> None + super(RawExpression, self).__init__() + self.text = text + + def __str__(self): + return str(self.text) + + +# pylint: disable=redefined-builtin +class AssignmentExpression(Expression): + def __init__(self, type, modifier, name, rhs, obj): + super(AssignmentExpression, self).__init__() + self.type = type + self.modifier = modifier + self.name = name + self.rhs = safe_exp(rhs) + self.requires.append(self.rhs) + self.obj = obj + + def __str__(self): + type_ = self.type + return u"{} {}{} = {}".format(type_, self.modifier, self.name, self.rhs) + + def has_side_effects(self): + return self.rhs.has_side_effects() + + +class ExpressionList(Expression): + def __init__(self, *args): + super(ExpressionList, self).__init__() + # Remove every None on end + args = list(args) + while args and args[-1] is None: + args.pop() + self.args = [] + for arg in args: + exp = safe_exp(arg) + self.requires.append(exp) + self.args.append(exp) + + def __str__(self): + text = u", ".join(unicode(x) for x in self.args) + return indent_all_but_first_and_last(text) + + +class TemplateArguments(Expression): + def __init__(self, *args): # type: (*SafeExpType) -> None + super(TemplateArguments, self).__init__() + self.args = ExpressionList(*args) + self.requires.append(self.args) + + def __str__(self): + return u'<{}>'.format(self.args) + + +class CallExpression(Expression): + def __init__(self, base, *args): # type: (Expression, *SafeExpType) -> None + super(CallExpression, self).__init__() + self.base = base + if args and isinstance(args[0], TemplateArguments): + self.template_args = args[0] + self.requires.append(self.template_args) + args = args[1:] + else: + self.template_args = None + self.args = ExpressionList(*args) + self.requires.append(self.args) + + def __str__(self): + if self.template_args is not None: + return u'{}{}({})'.format(self.base, self.template_args, self.args) + return u'{}({})'.format(self.base, self.args) + + +class StructInitializer(Expression): + def __init__(self, base, *args): # type: (Expression, *Tuple[str, SafeExpType]) -> None + super(StructInitializer, self).__init__() + self.base = base + if isinstance(base, Expression): + self.requires.append(base) + if not isinstance(args, OrderedDict): + args = OrderedDict(args) + self.args = OrderedDict() + for key, value in args.iteritems(): + if value is None: + continue + exp = safe_exp(value) + self.args[key] = exp + self.requires.append(exp) + + def __str__(self): + cpp = u'{}{{\n'.format(self.base) + for key, value in self.args.iteritems(): + cpp += u' .{} = {},\n'.format(key, value) + cpp += u'}' + return cpp + + +class ArrayInitializer(Expression): + def __init__(self, *args, **kwargs): # type: (*Any, **Any) -> None + super(ArrayInitializer, self).__init__() + self.multiline = kwargs.get('multiline', True) + self.args = [] + for arg in args: + if arg is None: + continue + exp = safe_exp(arg) + self.args.append(exp) + self.requires.append(exp) + + def __str__(self): + if not self.args: + return u'{}' + if self.multiline: + cpp = u'{\n' + for arg in self.args: + cpp += u' {},\n'.format(arg) + cpp += u'}' + else: + cpp = u'{' + u', '.join(str(arg) for arg in self.args) + u'}' + return cpp + + +class ParameterExpression(Expression): + def __init__(self, type, id): + super(ParameterExpression, self).__init__() + self.type = type + self.id = id + + def __str__(self): + return u"{} {}".format(self.type, self.id) + + +class ParameterListExpression(Expression): + def __init__(self, *parameters): + super(ParameterListExpression, self).__init__() + self.parameters = [] + for parameter in parameters: + if not isinstance(parameter, ParameterExpression): + parameter = ParameterExpression(*parameter) + self.parameters.append(parameter) + self.requires.append(parameter) + + def __str__(self): + return u", ".join(unicode(x) for x in self.parameters) + + +class LambdaExpression(Expression): + def __init__(self, parts, parameters, capture='=', return_type=None): + super(LambdaExpression, self).__init__() + self.parts = parts + if not isinstance(parameters, ParameterListExpression): + parameters = ParameterListExpression(*parameters) + self.parameters = parameters + self.requires.append(self.parameters) + self.capture = capture + self.return_type = return_type + if return_type is not None: + self.requires.append(return_type) + for i in range(1, len(parts), 3): + self.requires.append(parts[i]) + + def __str__(self): + cpp = u'[{}]({})'.format(self.capture, self.parameters) + if self.return_type is not None: + cpp += u' -> {}'.format(self.return_type) + cpp += u' {{\n{}\n}}'.format(self.content) + return indent_all_but_first_and_last(cpp) + + @property + def content(self): + return u''.join(unicode(part) for part in self.parts) + + +class Literal(Expression): + def __str__(self): + raise NotImplementedError + + +class StringLiteral(Literal): + def __init__(self, string): # type: (Union[str, unicode]) -> None + super(StringLiteral, self).__init__() + self.string = string + + def __str__(self): + return u'{}'.format(cpp_string_escape(self.string)) + + +class IntLiteral(Literal): + def __init__(self, i): # type: (Union[int, long]) -> None + super(IntLiteral, self).__init__() + self.i = i + + def __str__(self): + if self.i > 4294967295: + return u'{}ULL'.format(self.i) + if self.i > 2147483647: + return u'{}UL'.format(self.i) + if self.i < -2147483648: + return u'{}LL'.format(self.i) + return unicode(self.i) + + +class BoolLiteral(Literal): + def __init__(self, binary): # type: (bool) -> None + super(BoolLiteral, self).__init__() + self.binary = binary + + def __str__(self): + return u"true" if self.binary else u"false" + + +class HexIntLiteral(Literal): + def __init__(self, i): # type: (int) -> None + super(HexIntLiteral, self).__init__() + self.i = HexInt(i) + + def __str__(self): + return str(self.i) + + +class FloatLiteral(Literal): + def __init__(self, value): # type: (float) -> None + super(FloatLiteral, self).__init__() + self.float_ = value + + def __str__(self): + return u"{:f}f".format(self.float_) + + +def safe_exp(obj # type: Union[Expression, bool, str, unicode, int, long, float, TimePeriod] + ): + # type: (...) -> Expression + if isinstance(obj, Expression): + return obj + elif isinstance(obj, bool): + return BoolLiteral(obj) + elif isinstance(obj, (str, unicode)): + return StringLiteral(obj) + elif isinstance(obj, HexInt): + return HexIntLiteral(obj) + elif isinstance(obj, (int, long)): + return IntLiteral(obj) + elif isinstance(obj, float): + return FloatLiteral(obj) + elif isinstance(obj, TimePeriodMicroseconds): + return IntLiteral(int(obj.total_microseconds)) + elif isinstance(obj, TimePeriodMilliseconds): + return IntLiteral(int(obj.total_milliseconds)) + elif isinstance(obj, TimePeriodSeconds): + return IntLiteral(int(obj.total_seconds)) + raise ValueError(u"Object is not an expression", obj) + + +class Statement(object): + def __init__(self): + pass + + def __str__(self): + raise NotImplementedError + + +class RawStatement(Statement): + def __init__(self, text): + super(RawStatement, self).__init__() + self.text = text + + def __str__(self): + return self.text + + +class ExpressionStatement(Statement): + def __init__(self, expression): + super(ExpressionStatement, self).__init__() + self.expression = safe_exp(expression) + + def __str__(self): + return u"{};".format(self.expression) + + +def statement(expression): # type: (Union[Expression, Statement]) -> Statement + if isinstance(expression, Statement): + return expression + return ExpressionStatement(expression) + + +def variable(id, # type: ID + rhs, # type: Expression + type=None # type: MockObj + ): + # type: (...) -> MockObj + rhs = safe_exp(rhs) + obj = MockObj(id, u'.') + id.type = type or id.type + assignment = AssignmentExpression(id.type, '', id, rhs, obj) + CORE.add(assignment) + CORE.register_variable(id, obj) + obj.requires.append(assignment) + return obj + + +def Pvariable(id, # type: ID + rhs, # type: Expression + has_side_effects=True, # type: bool + type=None # type: MockObj + ): + # type: (...) -> MockObj + 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) + id.type = type or id.type + assignment = AssignmentExpression(id.type, '*', id, rhs, obj) + CORE.add(assignment) + CORE.register_variable(id, obj) + obj.requires.append(assignment) + return obj + + +def add(expression, # type: Union[Expression, Statement] + require=True # type: bool + ): + # type: (...) -> None + CORE.add(expression, require=require) + + +def get_variable(id): # type: (ID) -> Generator[MockObj] + for var in CORE.get_variable(id): + yield None + yield var + + +def process_lambda(value, # type: Lambda + parameters, # type: List[Tuple[Expression, str]] + capture='=', # type: str + return_type=None # type: Optional[Expression] + ): + # type: (...) -> Generator[LambdaExpression] + from esphomeyaml.components.globals import GlobalVariableComponent + + if value is None: + yield + return + parts = value.parts[:] + for i, id in enumerate(value.requires_ids): + for full_id, var in CORE.get_variable_with_full_id(id): + yield + if full_id is not None and isinstance(full_id.type, MockObjClass) and \ + full_id.type.inherits_from(GlobalVariableComponent): + parts[i * 3 + 1] = var.value() + continue + + if parts[i * 3 + 2] == '.': + parts[i * 3 + 1] = var._ + else: + parts[i * 3 + 1] = var + parts[i * 3 + 2] = '' + yield LambdaExpression(parts, parameters, capture, return_type) + + +def templatable(value, # type: Any + input_type, # type: Expression + output_type # type: Optional[Expression] + ): + if isinstance(value, Lambda): + lambda_ = None + for lambda_ in process_lambda(value, [(input_type, 'x')], return_type=output_type): + yield None + yield lambda_ + else: + yield value + + +class MockObj(Expression): + def __init__(self, base, op=u'.', has_side_effects=True): + self.base = base + self.op = op + self._has_side_effects = has_side_effects + super(MockObj, self).__init__() + + def __getattr__(self, attr): # type: (str) -> MockObj + if attr == u'_': + obj = MockObj(u'{}{}'.format(self.base, self.op)) + obj.requires.append(self) + return obj + if attr == u'new': + obj = MockObj(u'new {}'.format(self.base), u'->') + obj.requires.append(self) + return obj + next_op = u'.' + if attr.startswith(u'P') and self.op not in ['::', '']: + attr = attr[1:] + next_op = u'->' + if attr.startswith(u'_'): + attr = attr[1:] + obj = MockObj(u'{}{}{}'.format(self.base, self.op, attr), next_op) + obj.requires.append(self) + return obj + + def __call__(self, *args, **kwargs): # type: (*Any, **Any) -> MockObj + call = CallExpression(self.base, *args) + obj = MockObj(call, self.op) + obj.requires.append(self) + obj.requires.append(call) + return obj + + def __str__(self): # type: () -> unicode + return unicode(self.base) + + def require(self): # type: () -> None + self.required = True + for require in self.requires: + if require.required: + continue + require.require() + + def template(self, args): # type: (Union[TemplateArguments, Expression]) -> MockObj + if not isinstance(args, TemplateArguments): + args = TemplateArguments(args) + obj = MockObj(u'{}{}'.format(self.base, args)) + obj.requires.append(self) + obj.requires.append(args) + return obj + + def namespace(self, name): # type: (str) -> MockObj + obj = MockObj(u'{}{}{}'.format(self.base, self.op, name), u'::') + obj.requires.append(self) + return obj + + def class_(self, name, *parents): # type: (str, *MockObjClass) -> MockObjClass + obj = MockObjClass(u'{}::{}'.format(self.base, name), u'.', parents=parents) + obj.requires.append(self) + return obj + + def struct(self, name): # type: (str) -> MockObjClass + return self.class_(name) + + def enum(self, name, is_class=False): # type: (str, bool) -> MockObj + if is_class: + return self.namespace(name) + + return self + + def operator(self, name): # type: (str) -> MockObj + if name == 'ref': + obj = MockObj(u'{} &'.format(self.base), u'') + obj.requires.append(self) + return obj + if name == 'ptr': + obj = MockObj(u'{} *'.format(self.base), u'') + obj.requires.append(self) + return obj + if name == "const": + obj = MockObj(u'const {}'.format(self.base), u'') + obj.requires.append(self) + return obj + raise NotImplementedError + + def has_side_effects(self): # type: () -> bool + return self._has_side_effects + + def __getitem__(self, item): # type: (Union[str, Expression]) -> MockObj + next_op = u'.' + if isinstance(item, str) and item.startswith(u'P'): + item = item[1:] + next_op = u'->' + obj = MockObj(u'{}[{}]'.format(self.base, item), next_op) + obj.requires.append(self) + if isinstance(item, Expression): + obj.requires.append(item) + return obj + + +class MockObjClass(MockObj): + def __init__(self, *args, **kwargs): + parens = kwargs.pop('parents') + MockObj.__init__(self, *args, **kwargs) + self._parents = [] + for paren in parens: + if not isinstance(paren, MockObjClass): + raise ValueError + self._parents.append(paren) + # pylint: disable=protected-access + self._parents += paren._parents + + def inherits_from(self, other): # type: (MockObjClass) -> bool + if self == other: + return True + for parent in self._parents: + if parent == other: + return True + return False + + def template(self, args): # type: (Union[TemplateArguments, Expression]) -> MockObjClass + if not isinstance(args, TemplateArguments): + args = TemplateArguments(args) + new_parents = self._parents[:] + new_parents.append(self) + obj = MockObjClass(u'{}{}'.format(self.base, args), parents=new_parents) + obj.requires.append(self) + obj.requires.append(args) + return obj diff --git a/esphomeyaml/cpp_helpers.py b/esphomeyaml/cpp_helpers.py new file mode 100644 index 0000000000..030e4b95e2 --- /dev/null +++ b/esphomeyaml/cpp_helpers.py @@ -0,0 +1,49 @@ +from esphomeyaml.const import CONF_INVERTED, CONF_MODE, CONF_NUMBER, CONF_PCF8574, \ + CONF_SETUP_PRIORITY +from esphomeyaml.core import CORE, EsphomeyamlError +from esphomeyaml.cpp_generator import IntLiteral, RawExpression +from esphomeyaml.cpp_types import GPIOInputPin, GPIOOutputPin + + +def generic_gpio_pin_expression_(conf, mock_obj, default_mode): + if conf is None: + return + number = conf[CONF_NUMBER] + inverted = conf.get(CONF_INVERTED) + if CONF_PCF8574 in conf: + from esphomeyaml.components import pcf8574 + + for hub in CORE.get_variable(conf[CONF_PCF8574]): + yield None + + if default_mode == u'INPUT': + mode = pcf8574.PCF8675_GPIO_MODES[conf.get(CONF_MODE, u'INPUT')] + yield hub.make_input_pin(number, mode, inverted) + return + elif default_mode == u'OUTPUT': + yield hub.make_output_pin(number, inverted) + return + else: + raise EsphomeyamlError(u"Unknown default mode {}".format(default_mode)) + if len(conf) == 1: + yield IntLiteral(number) + return + mode = RawExpression(conf.get(CONF_MODE, default_mode)) + yield mock_obj(number, mode, inverted) + + +def gpio_output_pin_expression(conf): + for exp in generic_gpio_pin_expression_(conf, GPIOOutputPin, 'OUTPUT'): + yield None + yield exp + + +def gpio_input_pin_expression(conf): + for exp in generic_gpio_pin_expression_(conf, GPIOInputPin, 'INPUT'): + yield None + yield exp + + +def setup_component(obj, config): + if CONF_SETUP_PRIORITY in config: + CORE.add(obj.set_setup_priority(config[CONF_SETUP_PRIORITY])) diff --git a/esphomeyaml/cpp_types.py b/esphomeyaml/cpp_types.py new file mode 100644 index 0000000000..493933a1cf --- /dev/null +++ b/esphomeyaml/cpp_types.py @@ -0,0 +1,35 @@ +from esphomeyaml.cpp_generator import MockObj + +global_ns = MockObj('', '') +float_ = global_ns.namespace('float') +bool_ = global_ns.namespace('bool') +std_ns = global_ns.namespace('std') +std_string = std_ns.string +std_vector = std_ns.vector +uint8 = global_ns.namespace('uint8_t') +uint16 = global_ns.namespace('uint16_t') +uint32 = global_ns.namespace('uint32_t') +int32 = global_ns.namespace('int32_t') +const_char_ptr = global_ns.namespace('const char *') +NAN = global_ns.namespace('NAN') +esphomelib_ns = global_ns # using namespace esphomelib; +NoArg = esphomelib_ns.NoArg +App = esphomelib_ns.App +io_ns = esphomelib_ns.namespace('io') +Nameable = esphomelib_ns.class_('Nameable') +Trigger = esphomelib_ns.class_('Trigger') +Action = esphomelib_ns.class_('Action') +Component = esphomelib_ns.class_('Component') +PollingComponent = esphomelib_ns.class_('PollingComponent', Component) +Application = esphomelib_ns.class_('Application') +optional = esphomelib_ns.class_('optional') +arduino_json_ns = global_ns.namespace('ArduinoJson') +JsonObject = arduino_json_ns.class_('JsonObject') +JsonObjectRef = JsonObject.operator('ref') +JsonObjectConstRef = JsonObjectRef.operator('const') +Controller = esphomelib_ns.class_('Controller') +StoringController = esphomelib_ns.class_('StoringController', Controller) + +GPIOPin = esphomelib_ns.class_('GPIOPin') +GPIOOutputPin = esphomelib_ns.class_('GPIOOutputPin', GPIOPin) +GPIOInputPin = esphomelib_ns.class_('GPIOInputPin', GPIOPin) diff --git a/esphomeyaml/dashboard/dashboard.py b/esphomeyaml/dashboard/dashboard.py index d12dc0fec8..0c13918b79 100644 --- a/esphomeyaml/dashboard/dashboard.py +++ b/esphomeyaml/dashboard/dashboard.py @@ -1,19 +1,24 @@ # pylint: disable=wrong-import-position from __future__ import print_function -import codecs +import collections import hmac import json import logging +import multiprocessing import os import random import subprocess +import threading -from esphomeyaml.const import CONF_ESPHOMEYAML, CONF_BUILD_PATH -from esphomeyaml.core import ESPHomeYAMLError -from esphomeyaml import const, core, __main__ +from tornado.log import access_log +from typing import Optional + +from esphomeyaml import const from esphomeyaml.__main__ import get_serial_ports -from esphomeyaml.helpers import relative_path +from esphomeyaml.core import EsphomeyamlError +from esphomeyaml.helpers import run_system_command +from esphomeyaml.storage_json import StorageJSON, ext_storage_path from esphomeyaml.util import shlex_quote try: @@ -52,7 +57,7 @@ class EsphomeyamlCommandWebSocket(tornado.websocket.WebSocketHandler): if self.proc is not None: return command = self.build_command(message) - _LOGGER.debug(u"WebSocket opened for command %s", [shlex_quote(x) for x in command]) + _LOGGER.info(u"Running command '%s'", ' '.join(shlex_quote(x) for x in command)) self.proc = tornado.process.Subprocess(command, stdout=tornado.process.Subprocess.STREAM, stderr=subprocess.STDOUT) @@ -166,11 +171,8 @@ class WizardRequestHandler(BaseHandler): self.redirect('/login') return kwargs = {k: ''.join(v) for k, v in self.request.arguments.iteritems()} - config = wizard.wizard_file(**kwargs) destination = os.path.join(CONFIG_DIR, kwargs['name'] + '.yaml') - with codecs.open(destination, 'w') as f_handle: - f_handle.write(config) - + wizard.wizard_write(path=destination, **kwargs) self.redirect('/?begin=True') @@ -181,13 +183,16 @@ class DownloadBinaryRequestHandler(BaseHandler): return configuration = self.get_argument('configuration') - config_file = os.path.join(CONFIG_DIR, configuration) - core.CONFIG_PATH = config_file - config = __main__.read_config(core.CONFIG_PATH) - build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH]) - path = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin') + storage_path = ext_storage_path(CONFIG_DIR, configuration) + storage_json = StorageJSON.load(storage_path) + if storage_json is None: + self.send_error() + return + + path = storage_json.firmware_bin_path self.set_header('Content-Type', 'application/octet-stream') - self.set_header("Content-Disposition", 'attachment; filename="{}.bin"'.format(core.NAME)) + filename = '{}.bin'.format(storage_json.name) + self.set_header("Content-Disposition", 'attachment; filename="{}"'.format(filename)) with open(path, 'rb') as f: while 1: data = f.read(16384) # or some other nice-sized chunk @@ -197,6 +202,67 @@ class DownloadBinaryRequestHandler(BaseHandler): self.finish() +def _list_yaml_files(): + files = [] + for file in os.listdir(CONFIG_DIR): + if not file.endswith('.yaml'): + continue + if file.startswith('.'): + continue + if file == 'secrets.yaml': + continue + files.append(file) + files.sort() + return files + + +def _list_dashboard_entries(): + files = _list_yaml_files() + return [DashboardEntry(file) for file in files] + + +class DashboardEntry(object): + def __init__(self, filename): + self.filename = filename + self._storage = None + self._loaded_storage = False + + @property + def full_path(self): # type: () -> str + return os.path.join(CONFIG_DIR, self.filename) + + @property + def storage(self): # type: () -> Optional[StorageJSON] + if not self._loaded_storage: + self._storage = StorageJSON.load(ext_storage_path(CONFIG_DIR, self.filename)) + self._loaded_storage = True + return self._storage + + @property + def address(self): + if self.storage is None: + return None + return self.storage.address + + @property + def name(self): + if self.storage is None: + return self.filename[:-len('.yaml')] + return self.storage.name + + @property + def esp_platform(self): + if self.storage is None: + return None + return self.storage.esp_platform + + @property + def board(self): + if self.storage is None: + return None + return self.storage.board + + class MainRequestHandler(BaseHandler): def get(self): if not self.is_authenticated(): @@ -204,11 +270,76 @@ class MainRequestHandler(BaseHandler): return begin = bool(self.get_argument('begin', False)) - files = sorted([f for f in os.listdir(CONFIG_DIR) if f.endswith('.yaml') and - not f.startswith('.')]) - full_path_files = [os.path.join(CONFIG_DIR, f) for f in files] - self.render("templates/index.html", files=files, full_path_files=full_path_files, - version=const.__version__, begin=begin) + entries = _list_dashboard_entries() + version = const.__version__ + docs_link = 'https://beta.esphomelib.com/esphomeyaml/' if 'b' in version else \ + 'https://esphomelib.com/esphomeyaml/' + + self.render("templates/index.html", entries=entries, + version=version, begin=begin, docs_link=docs_link) + + +def _ping_func(filename, address): + if os.name == 'nt': + command = ['ping', '-n', '1', address] + else: + command = ['ping', '-c', '1', address] + rc, _, _ = run_system_command(*command) + return filename, rc == 0 + + +class PingThread(threading.Thread): + def run(self): + pool = multiprocessing.Pool(processes=8) + + while not STOP_EVENT.is_set(): + # Only do pings if somebody has the dashboard open + PING_REQUEST.wait() + PING_REQUEST.clear() + + def callback(ret): + PING_RESULT[ret[0]] = ret[1] + + entries = _list_dashboard_entries() + queue = collections.deque() + for entry in entries: + if entry.address is None: + PING_RESULT[entry.filename] = None + continue + + result = pool.apply_async(_ping_func, (entry.filename, entry.address), + callback=callback) + queue.append(result) + + while queue: + item = queue[0] + if item.ready(): + queue.popleft() + continue + + try: + item.get(0.1) + except multiprocessing.TimeoutError: + pass + + if STOP_EVENT.is_set(): + pool.terminate() + return + + +class PingRequestHandler(BaseHandler): + def get(self): + if not self.is_authenticated(): + self.redirect('/login') + return + + PING_REQUEST.set() + self.write(json.dumps(PING_RESULT)) + + +PING_RESULT = {} # type: dict +STOP_EVENT = threading.Event() +PING_REQUEST = threading.Event() class LoginHandler(BaseHandler): @@ -227,8 +358,25 @@ class LoginHandler(BaseHandler): def make_app(debug=False): + def log_function(handler): + if handler.get_status() < 400: + log_method = access_log.info + + if isinstance(handler, SerialPortRequestHandler) and not debug: + return + if isinstance(handler, PingRequestHandler) and not debug: + return + elif handler.get_status() < 500: + log_method = access_log.warning + else: + log_method = access_log.error + + request_time = 1000.0 * handler.request.request_time() + log_method("%d %s %.2fms", handler.get_status(), + handler._request_summary(), request_time) + static_path = os.path.join(os.path.dirname(__file__), 'static') - return tornado.web.Application([ + app = tornado.web.Application([ (r"/", MainRequestHandler), (r"/login", LoginHandler), (r"/logs", EsphomeyamlLogsHandler), @@ -240,9 +388,11 @@ def make_app(debug=False): (r"/hass-config", EsphomeyamlHassConfigHandler), (r"/download.bin", DownloadBinaryRequestHandler), (r"/serial-ports", SerialPortRequestHandler), + (r"/ping", PingRequestHandler), (r"/wizard.html", WizardRequestHandler), (r'/static/(.*)', tornado.web.StaticFileHandler, {'path': static_path}), - ], debug=debug, cookie_secret=PASSWORD) + ], debug=debug, cookie_secret=PASSWORD, log_function=log_function) + return app def start_web_server(args): @@ -250,7 +400,7 @@ def start_web_server(args): global PASSWORD if tornado is None: - raise ESPHomeYAMLError("Attempted to load dashboard, but tornado is not installed! " + raise EsphomeyamlError("Attempted to load dashboard, but tornado is not installed! " "Please run \"pip2 install tornado esptool\" in your terminal.") CONFIG_DIR = args.configuration @@ -282,7 +432,12 @@ def start_web_server(args): webbrowser.open('localhost:{}'.format(args.port)) + ping_thread = PingThread() + ping_thread.start() try: tornado.ioloop.IOLoop.current().start() except KeyboardInterrupt: _LOGGER.info("Shutting down...") + STOP_EVENT.set() + PING_REQUEST.set() + ping_thread.join() diff --git a/esphomeyaml/dashboard/templates/index.html b/esphomeyaml/dashboard/templates/index.html index 9ac93d0a9d..4fba0fcdb8 100644 --- a/esphomeyaml/dashboard/templates/index.html +++ b/esphomeyaml/dashboard/templates/index.html @@ -157,6 +157,65 @@ .dropdown-trigger { cursor: pointer; } + + /* https://github.com/tnhu/status-indicator/blob/master/styles.css */ + .status-indicator .status-indicator-icon { + display: inline-block; + border-radius: 50%; + width: 10px; + height: 10px; + } + + .status-indicator.unknown .status-indicator-icon { + background-color: rgb(216, 226, 233); + } + + .status-indicator.unknown .status-indicator-text::after { + content: "Unknown status"; + } + + .status-indicator.offline .status-indicator-icon { + background-color: rgb(255, 77, 77); + } + + .status-indicator.offline .status-indicator-text::after { + content: "Offline"; + } + + .status-indicator.not-responding .status-indicator-icon { + background-color: rgb(255, 170, 0); + } + + .status-indicator.not-responding .status-indicator-text::after { + content: "Not Responding"; + } + + @keyframes status-indicator-pulse-online { + 0% { + box-shadow: 0 0 0 0 rgba(75, 210, 143, .5); + } + 25% { + box-shadow: 0 0 0 10px rgba(75, 210, 143, 0); + } + 30% { + box-shadow: 0 0 0 0 rgba(75, 210, 143, 0); + } + } + + .status-indicator.online .status-indicator-icon { + background-color: rgb(75, 210, 143); + animation-duration: 5s; + animation-timing-function: ease-in-out; + animation-iteration-count: infinite; + animation-direction: normal; + animation-delay: 0s; + animation-fill-mode: none; + animation-name: status-indicator-pulse-online; + } + + .status-indicator.online .status-indicator-text::after { + content: "Online"; + } @@ -189,7 +248,7 @@
- {% for i, (file, full_path) in enumerate(zip(files, full_path_files)) %} + {% for i, entry in enumerate(entries) %}
@@ -199,23 +258,25 @@
- {{ escape(file) }} + {{ escape(entry.name) }} more_vert

- Full path: {{ escape(full_path) }} + + + . Full path: {{ escape(entry.full_path) }}

@@ -526,7 +587,7 @@ @@ -564,6 +625,50 @@ } const wsUrl = wsProtocol + '//' + window.location.hostname + ':' + window.location.port; + let isFetchingPing = false; + const fetchPing = () => { + if (isFetchingPing) + return; + isFetchingPing = true; + + fetch('/ping', {credentials: "same-origin"}).then(res => res.json()) + .then(response => { + for (let filename in response) { + let node = document.querySelector(`.status-indicator[data-node="${filename}"]`); + if (node === null) + continue; + + let status = response[filename]; + let klass; + if (status === null) { + klass = 'unknown'; + } else if (status === true) { + klass = 'online'; + node.setAttribute('data-last-connected', Date.now().toString()); + } else if (node.hasAttribute('data-last-connected')) { + const attr = parseInt(node.getAttribute('data-last-connected')); + if (Date.now() - attr <= 5000) { + klass = 'not-responding'; + } else { + klass = 'offline'; + } + } else { + klass = 'offline'; + } + + if (node.classList.contains(klass)) + continue; + + node.classList.remove('unknown', 'online', 'offline', 'not-responding'); + node.classList.add(klass); + } + + isFetchingPing = false; + }); + }; + setInterval(fetchPing, 2000); + fetchPing(); + const portSelect = document.querySelector('.nav-wrapper select'); let ports = []; @@ -986,7 +1091,7 @@ setupWizardStart.addEventListener('click', startWizard); -{% if len(files) == 0 %} +{% if len(entries) == 0 %}