From a827b518876cb82ba864640e37d55e485f36f577 Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Tue, 12 Jun 2018 21:18:04 +0200 Subject: [PATCH] Add ESP32 BLE Beacon --- esphomeyaml/__main__.py | 15 ++-- .../components/binary_sensor/__init__.py | 62 ++++++++++++-- .../{esp32_ble.py => esp32_ble_tracker.py} | 4 +- .../binary_sensor/remote_receiver.py | 81 +++++++++++++++++++ esphomeyaml/components/esp32_ble.py | 25 +----- esphomeyaml/components/esp32_ble_beacon.py | 35 ++++++++ esphomeyaml/components/esp32_ble_tracker.py | 24 ++++++ esphomeyaml/components/mqtt.py | 5 +- esphomeyaml/components/status_led.py | 23 ++++++ esphomeyaml/components/wifi.py | 8 +- esphomeyaml/config_validation.py | 5 ++ esphomeyaml/const.py | 6 ++ esphomeyaml/writer.py | 17 ++++ esphomeyaml/yaml_util.py | 6 ++ 14 files changed, 274 insertions(+), 42 deletions(-) rename esphomeyaml/components/binary_sensor/{esp32_ble.py => esp32_ble_tracker.py} (89%) create mode 100644 esphomeyaml/components/binary_sensor/remote_receiver.py create mode 100644 esphomeyaml/components/esp32_ble_beacon.py create mode 100644 esphomeyaml/components/esp32_ble_tracker.py create mode 100644 esphomeyaml/components/status_led.py diff --git a/esphomeyaml/__main__.py b/esphomeyaml/__main__.py index 22c9891801..601cd49565 100644 --- a/esphomeyaml/__main__.py +++ b/esphomeyaml/__main__.py @@ -9,9 +9,9 @@ from datetime import datetime from esphomeyaml import const, core, mqtt, wizard, writer, yaml_util from esphomeyaml.config import core_to_code, get_component, iter_components, read_config -from esphomeyaml.const import CONF_BAUD_RATE, CONF_DOMAIN, CONF_ESPHOMEYAML, CONF_HOSTNAME, \ - CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI, ESP_PLATFORM_ESP8266, \ - CONF_NETWORKS, CONF_BUILD_PATH +from esphomeyaml.const import CONF_BAUD_RATE, CONF_BUILD_PATH, CONF_DOMAIN, CONF_ESPHOMEYAML, \ + CONF_HOSTNAME, CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI, \ + ESP_PLATFORM_ESP8266 from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, _EXPRESSIONS, add, \ add_job, color, flush_tasks, indent, quote, statement @@ -143,9 +143,7 @@ def write_cpp(config): exp = exp.rhs all_code.append(unicode(statement(exp))) - platformio_ini_s = writer.get_ini_content(config) - ini_path = os.path.join(get_base_path(config), 'platformio.ini') - writer.write_platformio_ini(platformio_ini_s, ini_path) + writer.write_platformio_project(config, get_base_path(config)) code_s = indent('\n'.join(line.rstrip() for line in all_code)) cpp_path = os.path.join(get_base_path(config), 'src', 'main.cpp') @@ -162,9 +160,8 @@ def compile_program(args, config): def get_upload_host(config): - has_networks = bool(config[CONF_WIFI].get(CONF_NETWORKS)) - if has_networks and CONF_MANUAL_IP in config[CONF_WIFI][CONF_NETWORKS][0]: - host = str(config[CONF_WIFI][CONF_NETWORKS][0][CONF_MANUAL_IP][CONF_STATIC_IP]) + if CONF_MANUAL_IP in config[CONF_WIFI]: + host = str(config[CONF_WIFI][CONF_MANUAL_IP][CONF_STATIC_IP]) elif CONF_HOSTNAME in config[CONF_WIFI]: host = config[CONF_WIFI][CONF_HOSTNAME] + config[CONF_WIFI][CONF_DOMAIN] else: diff --git a/esphomeyaml/components/binary_sensor/__init__.py b/esphomeyaml/components/binary_sensor/__init__.py index 226eb70ee0..902983bea6 100644 --- a/esphomeyaml/components/binary_sensor/__init__.py +++ b/esphomeyaml/components/binary_sensor/__init__.py @@ -2,11 +2,12 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml import automation -from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INVERTED, CONF_MAX_LENGTH, \ - CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, CONF_ON_DOUBLE_CLICK, CONF_ON_PRESS, \ - CONF_ON_RELEASE, CONF_TRIGGER_ID, CONF_INTERNAL -from esphomeyaml.helpers import App, NoArg, Pvariable, add, esphomelib_ns, setup_mqtt_component, \ - add_job +from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INTERNAL, CONF_INVERTED, \ + CONF_MAX_LENGTH, CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, CONF_ON_DOUBLE_CLICK, \ + CONF_ON_PRESS, CONF_ON_RELEASE, CONF_TRIGGER_ID, CONF_FILTERS, CONF_INVERT, CONF_DELAYED_ON, \ + CONF_DELAYED_OFF, CONF_LAMBDA +from esphomeyaml.helpers import App, NoArg, Pvariable, add, add_job, esphomelib_ns, \ + setup_mqtt_component, bool_, process_lambda, ArrayInitializer DEVICE_CLASSES = [ '', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas', @@ -25,13 +26,27 @@ ReleaseTrigger = binary_sensor_ns.ReleaseTrigger ClickTrigger = binary_sensor_ns.ClickTrigger DoubleClickTrigger = binary_sensor_ns.DoubleClickTrigger BinarySensor = binary_sensor_ns.BinarySensor +InvertFilter = binary_sensor_ns.InvertFilter +LambdaFilter = binary_sensor_ns.LambdaFilter +DelayedOnFilter = binary_sensor_ns.DelayedOnFilter +DelayedOffFilter = binary_sensor_ns.DelayedOffFilter MQTTBinarySensorComponent = binary_sensor_ns.MQTTBinarySensorComponent +FILTER_KEYS = [CONF_INVERT, CONF_DELAYED_ON, CONF_DELAYED_OFF, CONF_LAMBDA] + +FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({ + vol.Optional(CONF_INVERT): None, + vol.Optional(CONF_DELAYED_ON): cv.positive_time_period_milliseconds, + vol.Optional(CONF_DELAYED_OFF): cv.positive_time_period_milliseconds, + vol.Optional(CONF_LAMBDA): cv.lambda_, +}, cv.has_exactly_one_key(*FILTER_KEYS))]) + BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({ cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTBinarySensorComponent), cv.GenerateID(): cv.declare_variable_id(BinarySensor), - vol.Optional(CONF_INVERTED): cv.boolean, + vol.Optional(CONF_DEVICE_CLASS): vol.All(vol.Lower, cv.one_of(*DEVICE_CLASSES)), + vol.Optional(CONF_FILTERS): FILTERS_SCHEMA, vol.Optional(CONF_ON_PRESS): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(PressTrigger), })]), @@ -49,11 +64,41 @@ BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({ vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds, vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds, })]), + + vol.Optional(CONF_INVERTED): cv.invalid( + "The inverted binary_sensor property has been replaced by the " + "new 'invert' binary sensor filter. Please see " + "https://esphomelib.com/esphomeyaml/components/binary_sensor/index.html." + ), }) BINARY_SENSOR_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(BINARY_SENSOR_SCHEMA.schema) +def setup_filter(config): + if CONF_INVERT in config: + yield InvertFilter.new() + elif CONF_DELAYED_OFF in config: + yield App.register_component(DelayedOffFilter.new(config[CONF_DELAYED_OFF])) + elif CONF_DELAYED_ON in config: + yield App.register_component(DelayedOnFilter.new(config[CONF_DELAYED_ON])) + elif CONF_LAMBDA in config: + lambda_ = None + for lambda_ in process_lambda(config[CONF_LAMBDA], [(bool_, 'x')]): + yield None + yield LambdaFilter.new(lambda_) + + +def setup_filters(config): + filters = [] + for conf in config: + filter = None + for filter in setup_filter(conf): + yield None + filters.append(filter) + yield ArrayInitializer(*filters) + + def setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config): if CONF_INTERNAL in config: add(binary_sensor_var.set_internal(CONF_INTERNAL)) @@ -61,6 +106,11 @@ def setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config): add(binary_sensor_var.set_device_class(config[CONF_DEVICE_CLASS])) if CONF_INVERTED in config: add(binary_sensor_var.set_inverted(config[CONF_INVERTED])) + if CONF_FILTERS in config: + filters = None + for filters in setup_filters(config[CONF_FILTERS]): + yield + add(binary_sensor_var.add_filters(filters)) for conf in config.get(CONF_ON_PRESS, []): rhs = binary_sensor_var.make_press_trigger() diff --git a/esphomeyaml/components/binary_sensor/esp32_ble.py b/esphomeyaml/components/binary_sensor/esp32_ble_tracker.py similarity index 89% rename from esphomeyaml/components/binary_sensor/esp32_ble.py rename to esphomeyaml/components/binary_sensor/esp32_ble_tracker.py index 9fce2f042a..3ee313ff84 100644 --- a/esphomeyaml/components/binary_sensor/esp32_ble.py +++ b/esphomeyaml/components/binary_sensor/esp32_ble_tracker.py @@ -2,13 +2,13 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml.components import binary_sensor -from esphomeyaml.components.esp32_ble import ESP32BLETracker +from esphomeyaml.components.esp32_ble_tracker import ESP32BLETracker from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME, ESP_PLATFORM_ESP32 from esphomeyaml.core import HexInt from esphomeyaml.helpers import ArrayInitializer, get_variable ESP_PLATFORMS = [ESP_PLATFORM_ESP32] -DEPENDENCIES = ['esp32_ble'] +DEPENDENCIES = ['esp32_ble_tracker'] CONF_ESP32_BLE_ID = 'esp32_ble_id' diff --git a/esphomeyaml/components/binary_sensor/remote_receiver.py b/esphomeyaml/components/binary_sensor/remote_receiver.py new file mode 100644 index 0000000000..27d7da1fe0 --- /dev/null +++ b/esphomeyaml/components/binary_sensor/remote_receiver.py @@ -0,0 +1,81 @@ +import voluptuous as vol + +import esphomeyaml.config_validation as cv +from esphomeyaml.components import binary_sensor +from esphomeyaml.components.remote_receiver import RemoteReceiverComponent, remote_ns +from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_COMMAND, CONF_DATA, \ + CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_RAW, CONF_SONY +from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, get_variable + +DEPENDENCIES = ['remote_receiver'] + +IR_KEYS = [CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, CONF_RAW] + +CONF_REMOTE_RECEIVER_ID = 'remote_receiver_id' +CONF_RECEIVER_ID = 'receiver_id' + +RemoteReceiver = remote_ns.RemoteReceiver +LGReceiver = remote_ns.LGReceiver +NECReceiver = remote_ns.NECReceiver +PanasonicReceiver = remote_ns.PanasonicReceiver +RawReceiver = remote_ns.RawReceiver +SonyReceiver = remote_ns.SonyReceiver + +PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_LG): vol.Schema({ + vol.Required(CONF_DATA): cv.hex_uint32_t, + vol.Optional(CONF_NBITS, default=28): vol.All(vol.Coerce(int), cv.one_of(28, 32)), + }), + vol.Optional(CONF_NEC): vol.Schema({ + vol.Required(CONF_ADDRESS): cv.hex_uint16_t, + vol.Required(CONF_COMMAND): cv.hex_uint16_t, + }), + vol.Optional(CONF_SONY): vol.Schema({ + vol.Required(CONF_DATA): cv.hex_uint32_t, + vol.Optional(CONF_NBITS, default=12): vol.All(vol.Coerce(int), cv.one_of(12, 15, 20)), + }), + vol.Optional(CONF_PANASONIC): vol.Schema({ + vol.Required(CONF_ADDRESS): cv.hex_uint16_t, + vol.Required(CONF_COMMAND): cv.hex_uint32_t, + }), + vol.Optional(CONF_RAW): vol.Schema({ + vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)], + vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)), + }), + cv.GenerateID(CONF_REMOTE_RECEIVER_ID): cv.use_variable_id(RemoteReceiverComponent), + cv.GenerateID(CONF_RECEIVER_ID): cv.declare_variable_id(RemoteReceiver), +}), cv.has_exactly_one_key(*IR_KEYS)) + + +def receiver_base(config): + if CONF_LG in config: + conf = config[CONF_LG] + return LGReceiver.new(config[CONF_NAME], conf[CONF_DATA], conf[CONF_NBITS]) + elif CONF_NEC in config: + conf = config[CONF_NEC] + return NECReceiver.new(config[CONF_NAME], conf[CONF_ADDRESS], conf[CONF_COMMAND]) + elif CONF_PANASONIC in config: + conf = config[CONF_PANASONIC] + return PanasonicReceiver.new(config[CONF_NAME], conf[CONF_ADDRESS], conf[CONF_COMMAND]) + elif CONF_SONY in config: + conf = config[CONF_SONY] + return SonyReceiver.new(config[CONF_NAME], conf[CONF_DATA], conf[CONF_NBITS]) + elif CONF_RAW in config: + conf = config[CONF_RAW] + data = ArrayInitializer(*conf[CONF_DATA]) + return RawReceiver.new(data, conf[CONF_CARRIER_FREQUENCY]) + else: + raise ValueError("Unknown receiver type {}".format(config)) + + +def to_code(config): + remote = None + for remote in get_variable(config[CONF_REMOTE_RECEIVER_ID]): + yield + rhs = App.register_component(receiver_base(config)) + receiver = Pvariable(config[CONF_RECEIVER_ID], rhs) + + binary_sensor.register_binary_sensor(remote.add_decoder(receiver), config) + + +BUILD_FLAGS = '-DUSE_REMOTE_RECEIVER' diff --git a/esphomeyaml/components/esp32_ble.py b/esphomeyaml/components/esp32_ble.py index c99762b8fc..adf60a7290 100644 --- a/esphomeyaml/components/esp32_ble.py +++ b/esphomeyaml/components/esp32_ble.py @@ -1,24 +1,5 @@ -import voluptuous as vol - from esphomeyaml import config_validation as cv -from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32 -from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns -ESP_PLATFORMS = [ESP_PLATFORM_ESP32] - -ESP32BLETracker = esphomelib_ns.ESP32BLETracker - -CONFIG_SCHEMA = vol.Schema({ - cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker), - vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds, -}) - - -def to_code(config): - rhs = App.make_esp32_ble_tracker() - ble = Pvariable(config[CONF_ID], rhs) - if CONF_SCAN_INTERVAL in config: - add(ble.set_scan_interval(config[CONF_SCAN_INTERVAL])) - - -BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER' +CONFIG_SCHEMA = cv.invalid("The 'esp32_ble' component has been renamed to the 'esp32_ble_tracker' " + "component in order to avoid confusion with the new 'esp32_ble_beacon' " + "component.") diff --git a/esphomeyaml/components/esp32_ble_beacon.py b/esphomeyaml/components/esp32_ble_beacon.py new file mode 100644 index 0000000000..70bd410b27 --- /dev/null +++ b/esphomeyaml/components/esp32_ble_beacon.py @@ -0,0 +1,35 @@ +import voluptuous as vol + +from esphomeyaml import config_validation as cv +from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32, CONF_UUID, CONF_TYPE +from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, RawExpression, ArrayInitializer + +ESP_PLATFORMS = [ESP_PLATFORM_ESP32] + +ESP32BLETracker = esphomelib_ns.ESP32BLETracker + +CONF_MAJOR = 'major' +CONF_MINOR = 'minor' + +CONFIG_SCHEMA = vol.Schema({ + cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker), + vol.Required(CONF_TYPE): vol.All(vol.Upper, cv.one_of('IBEACON')), + vol.Required(CONF_UUID): cv.uuid, + vol.Optional(CONF_MAJOR): cv.uint16_t, + vol.Optional(CONF_MINOR): cv.uint16_t, + vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds, +}) + + +def to_code(config): + uuid = config[CONF_UUID].hex + uuid_arr = [RawExpression('0x{}'.format(uuid[i:i+2])) for i in range(0, len(uuid), 2)] + rhs = App.make_esp32_ble_beacon(ArrayInitializer(*uuid_arr, multiline=False)) + ble = Pvariable(config[CONF_ID], rhs) + if CONF_MAJOR in config: + add(ble.set_major(config[CONF_MAJOR])) + if CONF_MINOR in config: + add(ble.set_minor(config[CONF_MINOR])) + + +BUILD_FLAGS = '-DUSE_ESP32_BLE_BEACON' diff --git a/esphomeyaml/components/esp32_ble_tracker.py b/esphomeyaml/components/esp32_ble_tracker.py new file mode 100644 index 0000000000..c99762b8fc --- /dev/null +++ b/esphomeyaml/components/esp32_ble_tracker.py @@ -0,0 +1,24 @@ +import voluptuous as vol + +from esphomeyaml import config_validation as cv +from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32 +from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns + +ESP_PLATFORMS = [ESP_PLATFORM_ESP32] + +ESP32BLETracker = esphomelib_ns.ESP32BLETracker + +CONFIG_SCHEMA = vol.Schema({ + cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker), + vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds, +}) + + +def to_code(config): + rhs = App.make_esp32_ble_tracker() + ble = Pvariable(config[CONF_ID], rhs) + if CONF_SCAN_INTERVAL in config: + add(ble.set_scan_interval(config[CONF_SCAN_INTERVAL])) + + +BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER' diff --git a/esphomeyaml/components/mqtt.py b/esphomeyaml/components/mqtt.py index 4b45769160..a687872453 100644 --- a/esphomeyaml/components/mqtt.py +++ b/esphomeyaml/components/mqtt.py @@ -8,7 +8,7 @@ from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, C CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_KEEPALIVE, CONF_LOG_TOPIC, \ CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, \ CONF_SSL_FINGERPRINTS, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, \ - CONF_WILL_MESSAGE + CONF_WILL_MESSAGE, CONF_REBOOT_TIMEOUT from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \ StructInitializer, \ TemplateArguments, add, esphomelib_ns, optional, std_string @@ -71,6 +71,7 @@ CONFIG_SCHEMA = vol.Schema({ vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266, cv.ensure_list, [validate_fingerprint]), vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds, + vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds, vol.Optional(CONF_ON_MESSAGE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger), vol.Required(CONF_TOPIC): cv.publish_topic, @@ -130,6 +131,8 @@ def to_code(config): add(mqtt.add_ssl_fingerprint(ArrayInitializer(*arr, multiline=False))) if CONF_KEEPALIVE in config: add(mqtt.set_keep_alive(config[CONF_KEEPALIVE])) + if CONF_REBOOT_TIMEOUT in 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]) diff --git a/esphomeyaml/components/status_led.py b/esphomeyaml/components/status_led.py new file mode 100644 index 0000000000..e72346941a --- /dev/null +++ b/esphomeyaml/components/status_led.py @@ -0,0 +1,23 @@ +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 + +StatusLED = esphomelib_ns.StatusLED + +CONFIG_SCHEMA = vol.Schema({ + cv.GenerateID(): cv.declare_variable_id(StatusLED), + vol.Optional(CONF_PIN): pins.gpio_output_pin_schema, +}) + + +def to_code(config): + pin = None + for pin in gpio_output_pin_expression(config[CONF_PIN]): + yield + rhs = App.make_status_led(pin) + Pvariable(config[CONF_ID], rhs) + + +BUILD_FLAGS = '-DUSE_STATUS_LED' diff --git a/esphomeyaml/components/wifi.py b/esphomeyaml/components/wifi.py index 661a507fd4..0b9fa2cbc8 100644 --- a/esphomeyaml/components/wifi.py +++ b/esphomeyaml/components/wifi.py @@ -3,8 +3,8 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml import core from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_DOMAIN, \ - CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_NETWORKS, CONF_PASSWORD, CONF_SSID, \ - CONF_STATIC_IP, CONF_SUBNET, ESP_PLATFORM_ESP8266 + CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, 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 @@ -78,6 +78,7 @@ CONFIG_SCHEMA = vol.All(vol.Schema({ vol.Optional(CONF_AP): WIFI_NETWORK_AP, vol.Optional(CONF_HOSTNAME): cv.hostname, vol.Optional(CONF_DOMAIN, default='.local'): cv.domainname, + vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds, }), validate) @@ -123,6 +124,9 @@ def to_code(config): if CONF_HOSTNAME in config: add(wifi.set_hostname(config[CONF_HOSTNAME])) + if CONF_REBOOT_TIMEOUT in config: + add(wifi.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT])) + def lib_deps(config): if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: diff --git a/esphomeyaml/config_validation.py b/esphomeyaml/config_validation.py index 9b3aa4c3d7..e9894d5032 100644 --- a/esphomeyaml/config_validation.py +++ b/esphomeyaml/config_validation.py @@ -4,6 +4,7 @@ from __future__ import print_function import logging import re +import uuid as uuid_ import voluptuous as vol @@ -348,6 +349,10 @@ def mac_address(value): return core.MACAddress(*parts_int) +def uuid(value): + return vol.Coerce(uuid_.UUID)(value) + + METRIC_SUFFIXES = { 'E': 1e18, 'P': 1e15, 'T': 1e12, 'G': 1e9, 'M': 1e6, 'k': 1e3, 'da': 10, 'd': 1e-1, 'c': 1e-2, 'm': 0.001, u'ยต': 1e-6, 'u': 1e-6, 'n': 1e-9, 'p': 1e-12, 'f': 1e-15, 'a': 1e-18, diff --git a/esphomeyaml/const.py b/esphomeyaml/const.py index 7917d73a59..d7689658be 100644 --- a/esphomeyaml/const.py +++ b/esphomeyaml/const.py @@ -241,6 +241,12 @@ CONF_IDLE = 'idle' CONF_NETWORKS = 'networks' CONF_INTERNAL = 'internal' CONF_BUILD_PATH = 'build_path' +CONF_REBOOT_TIMEOUT = 'reboot_timeout' +CONF_INVERT = 'invert' +CONF_DELAYED_ON = 'delayed_on' +CONF_DELAYED_OFF = 'delayed_off' +CONF_UUID = 'uuid' +CONF_TYPE = 'type' ESP32_BOARDS = [ 'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', diff --git a/esphomeyaml/writer.py b/esphomeyaml/writer.py index a3fd0bb5c9..ea85786c0d 100644 --- a/esphomeyaml/writer.py +++ b/esphomeyaml/writer.py @@ -176,6 +176,23 @@ def write_platformio_ini(content, path): f_handle.write(full_file) +def write_platformio_project(config, path): + platformio_ini = os.path.join(path, 'platformio.ini') + content = get_ini_content(config) + if 'esp32_ble_beacon' in config: + content += 'board_build.partitions = partitions.csv\n' + partitions_csv = os.path.join(path, 'partitions.csv') + if not os.path.isfile(partitions_csv): + with open(partitions_csv, "w") as f: + f.write("nvs, data, nvs, 0x009000, 0x005000,\n") + f.write("otadata, data, ota, 0x00e000, 0x002000,\n") + f.write("app0, app, ota_0, 0x010000, 0x190000,\n") + f.write("app1, app, ota_1, 0x200000, 0x190000,\n") + f.write("eeprom, data, 0x99, 0x390000, 0x001000,\n") + f.write("spiffs, data, spiffs, 0x391000, 0x00F000\n") + write_platformio_ini(content, platformio_ini) + + def write_cpp(code_s, path): if os.path.isfile(path): try: diff --git a/esphomeyaml/yaml_util.py b/esphomeyaml/yaml_util.py index c7c85cbc8a..341a3a67b9 100644 --- a/esphomeyaml/yaml_util.py +++ b/esphomeyaml/yaml_util.py @@ -4,6 +4,7 @@ import codecs import fnmatch import logging import os +import uuid from collections import OrderedDict import yaml @@ -285,6 +286,10 @@ def represent_id(_, data): return yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=data.id) +def represent_uuid(_, data): + return yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=str(data)) + + yaml.SafeDumper.add_representer( OrderedDict, lambda dumper, value: @@ -304,3 +309,4 @@ yaml.SafeDumper.add_representer(MACAddress, stringify_representer) yaml.SafeDumper.add_multi_representer(TimePeriod, represent_time_period) yaml.SafeDumper.add_multi_representer(Lambda, represent_lambda) yaml.SafeDumper.add_multi_representer(core.ID, represent_id) +yaml.SafeDumper.add_multi_representer(uuid.UUID, represent_uuid)