diff --git a/esphomeyaml/__main__.py b/esphomeyaml/__main__.py index 94ac0c30ea..aea995a142 100644 --- a/esphomeyaml/__main__.py +++ b/esphomeyaml/__main__.py @@ -139,7 +139,7 @@ def write_cpp(config): ini_path = os.path.join(get_base_path(config), 'platformio.ini') writer.write_platformio_ini(platformio_ini_s, ini_path) - code_s = indent('\n'.join(all_code)) + code_s = indent('\n'.join(line.rstrip() for line in all_code)) cpp_path = os.path.join(get_base_path(config), 'src', 'main.cpp') writer.write_cpp(code_s, cpp_path) return 0 diff --git a/esphomeyaml/components/ads1115.py b/esphomeyaml/components/ads1115.py index 7204ca6cf4..bee0d1191f 100644 --- a/esphomeyaml/components/ads1115.py +++ b/esphomeyaml/components/ads1115.py @@ -37,5 +37,4 @@ def to_code(config): add(ads1115.set_rate(RawExpression(RATES[conf[CONF_RATE]]))) -def build_flags(config): - return '-DUSE_ADS1115_SENSOR' +BUILD_FLAGS = '-DUSE_ADS1115_SENSOR' diff --git a/esphomeyaml/components/binary_sensor/__init__.py b/esphomeyaml/components/binary_sensor/__init__.py index 05371135f7..b8449353c2 100644 --- a/esphomeyaml/components/binary_sensor/__init__.py +++ b/esphomeyaml/components/binary_sensor/__init__.py @@ -35,5 +35,4 @@ def setup_mqtt_binary_sensor(obj, config): setup_mqtt_component(obj, config) -def build_flags(config): - return '-DUSE_BINARY_SENSOR' +BUILD_FLAGS = '-DUSE_BINARY_SENSOR' diff --git a/esphomeyaml/components/binary_sensor/gpio.py b/esphomeyaml/components/binary_sensor/gpio.py index 20ccb31814..c4e362aa13 100644 --- a/esphomeyaml/components/binary_sensor/gpio.py +++ b/esphomeyaml/components/binary_sensor/gpio.py @@ -21,5 +21,4 @@ def to_code(config): binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config) -def build_flags(config): - return '-DUSE_GPIO_BINARY_SENSOR' +BUILD_FLAGS = '-DUSE_GPIO_BINARY_SENSOR' diff --git a/esphomeyaml/components/binary_sensor/status.py b/esphomeyaml/components/binary_sensor/status.py index 749f0f72dc..5a48e1e674 100644 --- a/esphomeyaml/components/binary_sensor/status.py +++ b/esphomeyaml/components/binary_sensor/status.py @@ -17,5 +17,4 @@ def to_code(config): binary_sensor.setup_mqtt_binary_sensor(status.Pmqtt, config) -def build_flags(config): - return '-DUSE_STATUS_BINARY_SENSOR' +BUILD_FLAGS = '-DUSE_STATUS_BINARY_SENSOR' diff --git a/esphomeyaml/components/dallas.py b/esphomeyaml/components/dallas.py index 752c0ce7e6..850aaafd15 100644 --- a/esphomeyaml/components/dallas.py +++ b/esphomeyaml/components/dallas.py @@ -20,5 +20,4 @@ def to_code(config): Pvariable(DALLAS_COMPONENT_CLASS, conf[CONF_ID], rhs) -def build_flags(config): - return '-DUSE_DALLAS_SENSOR' +BUILD_FLAGS = '-DUSE_DALLAS_SENSOR' diff --git a/esphomeyaml/components/debug.py b/esphomeyaml/components/debug.py index c20969dc4c..533ffb8114 100644 --- a/esphomeyaml/components/debug.py +++ b/esphomeyaml/components/debug.py @@ -11,5 +11,4 @@ def to_code(config): add(App.make_debug_component()) -def build_flags(config): - return '-DUSE_DEBUG_COMPONENT' +BUILD_FLAGS = '-DUSE_DEBUG_COMPONENT' diff --git a/esphomeyaml/components/deep_sleep.py b/esphomeyaml/components/deep_sleep.py index c89db90457..c76205dd8d 100644 --- a/esphomeyaml/components/deep_sleep.py +++ b/esphomeyaml/components/deep_sleep.py @@ -38,5 +38,4 @@ def to_code(config): add(deep_sleep.set_run_duration(config[CONF_RUN_DURATION])) -def build_flags(config): - return '-DUSE_DEEP_SLEEP' +BUILD_FLAGS = '-DUSE_DEEP_SLEEP' diff --git a/esphomeyaml/components/fan/__init__.py b/esphomeyaml/components/fan/__init__.py index ddf4861da4..ef25200267 100644 --- a/esphomeyaml/components/fan/__init__.py +++ b/esphomeyaml/components/fan/__init__.py @@ -23,5 +23,4 @@ def setup_mqtt_fan(obj, config): setup_mqtt_component(obj, config) -def build_flags(config): - return '-DUSE_FAN' +BUILD_FLAGS = '-DUSE_FAN' diff --git a/esphomeyaml/components/i2c.py b/esphomeyaml/components/i2c.py index 459f29e7c2..870ff6efca 100644 --- a/esphomeyaml/components/i2c.py +++ b/esphomeyaml/components/i2c.py @@ -2,19 +2,23 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml import pins -from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA -from esphomeyaml.helpers import App, add +from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CONF_ID +from esphomeyaml.helpers import App, add, Pvariable CONFIG_SCHEMA = vol.Schema({ + cv.GenerateID('i2c'): cv.register_variable_id, vol.Required(CONF_SDA, default='SDA'): pins.input_output_pin, vol.Required(CONF_SCL, default='SCL'): pins.input_output_pin, vol.Optional(CONF_FREQUENCY): vol.All(cv.only_on_esp32, cv.positive_int), + vol.Optional(CONF_SCAN): cv.boolean, }) def to_code(config): - add(App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_FREQUENCY))) + rhs = App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_SCAN)) + i2c = Pvariable('I2CComponent', config[CONF_ID], rhs) + if CONF_FREQUENCY in config: + add(i2c.set_frequency(config[CONF_FREQUENCY])) -def build_flags(config): - return '-DUSE_I2C' +BUILD_FLAGS = '-DUSE_I2C' diff --git a/esphomeyaml/components/ir_transmitter.py b/esphomeyaml/components/ir_transmitter.py index b1be71bf29..4d9f972380 100644 --- a/esphomeyaml/components/ir_transmitter.py +++ b/esphomeyaml/components/ir_transmitter.py @@ -23,5 +23,4 @@ def to_code(config): Pvariable(IR_TRANSMITTER_COMPONENT_CLASS, conf[CONF_ID], rhs) -def build_flags(config): - return '-DUSE_IR_TRANSMITTER' +BUILD_FLAGS = '-DUSE_IR_TRANSMITTER' diff --git a/esphomeyaml/components/light/__init__.py b/esphomeyaml/components/light/__init__.py index 8ac678537a..1675a56292 100644 --- a/esphomeyaml/components/light/__init__.py +++ b/esphomeyaml/components/light/__init__.py @@ -12,5 +12,4 @@ def setup_light_component(obj, config): add(obj.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH])) -def build_flags(config): - return '-DUSE_LIGHT' +BUILD_FLAGS = '-DUSE_LIGHT' diff --git a/esphomeyaml/components/mqtt.py b/esphomeyaml/components/mqtt.py index ee216da8da..2ba4d42b1e 100644 --- a/esphomeyaml/components/mqtt.py +++ b/esphomeyaml/components/mqtt.py @@ -6,15 +6,26 @@ 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_SSL_FINGERPRINTS, CONF_ID, CONF_LOG_TOPIC, \ CONF_MQTT, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, CONF_TOPIC, \ - CONF_TOPIC_PREFIX, CONF_USERNAME, CONF_WILL_MESSAGE + CONF_TOPIC_PREFIX, CONF_USERNAME, CONF_WILL_MESSAGE, CONF_KEEPALIVE from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, StructInitializer, add, \ exp_empty_optional, RawExpression -MQTT_WILL_BIRTH_SCHEMA = vol.Any(None, vol.Schema({ + +def validate_message_just_topic(value): + value = cv.publish_topic(value) + return {CONF_TOPIC: value} + + +MQTT_MESSAGE_BASE = vol.Schema({ vol.Required(CONF_TOPIC): cv.publish_topic, - vol.Required(CONF_PAYLOAD): cv.mqtt_payload, vol.Optional(CONF_QOS, default=0): vol.All(vol.Coerce(int), vol.In([0, 1, 2])), vol.Optional(CONF_RETAIN, default=True): cv.boolean, +}) + +MQTT_MESSAGE_TEMPLATE_SCHEMA = vol.Any(None, MQTT_MESSAGE_BASE, validate_message_just_topic) + +MQTT_MESSAGE_SCHEMA = vol.Any(None, MQTT_MESSAGE_BASE.extend({ + vol.Required(CONF_PAYLOAD): cv.mqtt_payload, })) @@ -47,12 +58,13 @@ CONFIG_SCHEMA = vol.Schema({ vol.Optional(CONF_DISCOVERY): cv.boolean, vol.Optional(CONF_DISCOVERY_RETAIN): cv.boolean, vol.Optional(CONF_DISCOVERY_PREFIX): cv.publish_topic, - vol.Optional(CONF_BIRTH_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, - vol.Optional(CONF_WILL_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, + vol.Optional(CONF_BIRTH_MESSAGE): MQTT_MESSAGE_SCHEMA, + vol.Optional(CONF_WILL_MESSAGE): MQTT_MESSAGE_SCHEMA, vol.Optional(CONF_TOPIC_PREFIX): cv.publish_topic, - vol.Optional(CONF_LOG_TOPIC): cv.publish_topic, + vol.Optional(CONF_LOG_TOPIC): MQTT_MESSAGE_TEMPLATE_SCHEMA, vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266, cv.ensure_list, [validate_fingerprint]), + vol.Optional(CONF_KEEPALIVE): vol.All(cv.positive_time_period, cv.time_period_to_seconds) }) @@ -62,7 +74,7 @@ def exp_mqtt_message(config): exp = StructInitializer( 'mqtt::MQTTMessage', ('topic', config[CONF_TOPIC]), - ('payload', config[CONF_PAYLOAD]), + ('payload', config.get(CONF_PAYLOAD, "")), ('qos', config[CONF_QOS]), ('retain', config[CONF_RETAIN]) ) @@ -79,20 +91,34 @@ def to_code(config): discovery_retain = config.get(CONF_DISCOVERY_RETAIN, True) discovery_prefix = config.get(CONF_DISCOVERY_PREFIX, 'homeassistant') add(mqtt.set_discovery_info(discovery_prefix, discovery_retain)) - if CONF_BIRTH_MESSAGE in config: - add(mqtt.set_birth_message(config[CONF_BIRTH_MESSAGE])) - if CONF_WILL_MESSAGE in config: - add(mqtt.set_last_will(config[CONF_WILL_MESSAGE])) if CONF_TOPIC_PREFIX in config: add(mqtt.set_topic_prefix(config[CONF_TOPIC_PREFIX])) + if CONF_BIRTH_MESSAGE in config: + birth_message = config[CONF_BIRTH_MESSAGE] + if birth_message is None: + add(mqtt.disable_birth_message()) + else: + add(mqtt.set_birth_message(exp_mqtt_message(birth_message))) + if CONF_WILL_MESSAGE in config: + will_message = config[CONF_WILL_MESSAGE] + if will_message is None: + add(mqtt.disable_last_will()) + else: + add(mqtt.set_last_will(exp_mqtt_message(will_message))) if CONF_CLIENT_ID in config: add(mqtt.set_client_id(config[CONF_CLIENT_ID])) if CONF_LOG_TOPIC in config: - add(mqtt.set_log_topic(config[CONF_LOG_TOPIC])) + log_topic = config[CONF_LOG_TOPIC] + if log_topic is None: + add(mqtt.disable_log_message()) + else: + add(mqtt.set_log_topic(exp_mqtt_message(log_topic))) if CONF_SSL_FINGERPRINTS in config: for fingerprint in config[CONF_SSL_FINGERPRINTS]: arr = [RawExpression("0x{}".format(fingerprint[i:i + 2])) for i in range(0, 40, 2)] add(mqtt.add_ssl_fingerprint(ArrayInitializer(*arr, multiline=False))) + if CONF_KEEPALIVE in config: + add(mqtt.set_keep_alive(config[CONF_KEEPALIVE])) def required_build_flags(config): diff --git a/esphomeyaml/components/ota.py b/esphomeyaml/components/ota.py index dd50810de9..59f14b1970 100644 --- a/esphomeyaml/components/ota.py +++ b/esphomeyaml/components/ota.py @@ -45,5 +45,4 @@ def get_auth(config): return config[CONF_OTA].get(CONF_PASSWORD, '') -def build_flags(config): - return '-DUSE_OTA' +BUILD_FLAGS = '-DUSE_OTA' diff --git a/esphomeyaml/components/output/__init__.py b/esphomeyaml/components/output/__init__.py index 2cc957d243..c4f29fd6b1 100644 --- a/esphomeyaml/components/output/__init__.py +++ b/esphomeyaml/components/output/__init__.py @@ -25,5 +25,4 @@ def setup_output_platform(obj, config, skip_power_supply=False): add(obj.set_max_power(config[CONF_MAX_POWER])) -def build_flags(config): - return '-DUSE_OUTPUT' +BUILD_FLAGS = '-DUSE_OUTPUT' diff --git a/esphomeyaml/components/output/esp8266_pwm.py b/esphomeyaml/components/output/esp8266_pwm.py index 4d299d4e62..c89db95604 100644 --- a/esphomeyaml/components/output/esp8266_pwm.py +++ b/esphomeyaml/components/output/esp8266_pwm.py @@ -28,5 +28,4 @@ def to_code(config): output.setup_output_platform(gpio, config) -def build_flags(config): - return '-DUSE_ESP8266_PWM_OUTPUT' +BUILD_FLAGS = '-DUSE_ESP8266_PWM_OUTPUT' diff --git a/esphomeyaml/components/output/gpio.py b/esphomeyaml/components/output/gpio.py index 82f250c4cb..0a4d11248d 100644 --- a/esphomeyaml/components/output/gpio.py +++ b/esphomeyaml/components/output/gpio.py @@ -17,5 +17,4 @@ def to_code(config): output.setup_output_platform(gpio, config) -def build_flags(config): - return '-DUSE_GPIO_OUTPUT' +BUILD_FLAGS = '-DUSE_GPIO_OUTPUT' diff --git a/esphomeyaml/components/output/ledc.py b/esphomeyaml/components/output/ledc.py index f4076fd0fb..f6c8dd5c01 100644 --- a/esphomeyaml/components/output/ledc.py +++ b/esphomeyaml/components/output/ledc.py @@ -38,5 +38,4 @@ def to_code(config): output.setup_output_platform(ledc, config) -def build_flags(config): - return '-DUSE_LEDC_OUTPUT' +BUILD_FLAGS = '-DUSE_LEDC_OUTPUT' diff --git a/esphomeyaml/components/output/pca9685.py b/esphomeyaml/components/output/pca9685.py index fd29bc85c8..ffa8453280 100644 --- a/esphomeyaml/components/output/pca9685.py +++ b/esphomeyaml/components/output/pca9685.py @@ -25,5 +25,4 @@ def to_code(config): output.setup_output_platform(out, config, skip_power_supply=True) -def build_flags(config): - return '-DUSE_PCA9685_OUTPUT' +BUILD_FLAGS = '-DUSE_PCA9685_OUTPUT' diff --git a/esphomeyaml/components/pca9685.py b/esphomeyaml/components/pca9685.py index 5d40b8918f..5db5c065a1 100644 --- a/esphomeyaml/components/pca9685.py +++ b/esphomeyaml/components/pca9685.py @@ -33,5 +33,4 @@ def to_code(config): add(pca9685.set_phase_balancer(phase_balancer)) -def build_flags(config): - return '-DUSE_PCA9685_OUTPUT' +BUILD_FLAGS = '-DUSE_PCA9685_OUTPUT' diff --git a/esphomeyaml/components/pcf8574.py b/esphomeyaml/components/pcf8574.py new file mode 100644 index 0000000000..82be871292 --- /dev/null +++ b/esphomeyaml/components/pcf8574.py @@ -0,0 +1,24 @@ +import voluptuous as vol + +import esphomeyaml.config_validation as cv +from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_PCF8575 +from esphomeyaml.helpers import App, Pvariable + +DEPENDENCIES = ['i2c'] + +PCF8574_SCHEMA = vol.Schema({ + vol.Required(CONF_ID): cv.register_variable_id, + vol.Optional(CONF_ADDRESS, default=0x21): cv.i2c_address, + vol.Optional(CONF_PCF8575, default=False): cv.boolean, +}) + +CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCF8574_SCHEMA]) + + +def to_code(config): + for conf in config: + rhs = App.make_pcf8574_component(conf[CONF_ADDRESS], conf[CONF_PCF8575]) + Pvariable('io::PCF8574Component', conf[CONF_ID], rhs) + + +BUILD_FLAGS = '-DUSE_PCF8574' diff --git a/esphomeyaml/components/power_supply.py b/esphomeyaml/components/power_supply.py index 7cf8496210..8e06a16758 100644 --- a/esphomeyaml/components/power_supply.py +++ b/esphomeyaml/components/power_supply.py @@ -25,5 +25,4 @@ def to_code(config): add(psu.set_keep_on_time(conf[CONF_KEEP_ON_TIME])) -def build_flags(config): - return '-DUSE_OUTPUT' +BUILD_FLAGS = '-DUSE_OUTPUT' diff --git a/esphomeyaml/components/sensor/__init__.py b/esphomeyaml/components/sensor/__init__.py index 870fdb1a72..c72add513e 100644 --- a/esphomeyaml/components/sensor/__init__.py +++ b/esphomeyaml/components/sensor/__init__.py @@ -104,5 +104,4 @@ def register_sensor(var, config): setup_mqtt_sensor_component(mqtt_sensor, config) -def build_flags(config): - return '-DUSE_SENSOR' +BUILD_FLAGS = '-DUSE_SENSOR' diff --git a/esphomeyaml/components/sensor/adc.py b/esphomeyaml/components/sensor/adc.py index e11d80b8fb..14d309eb2e 100644 --- a/esphomeyaml/components/sensor/adc.py +++ b/esphomeyaml/components/sensor/adc.py @@ -36,5 +36,4 @@ def to_code(config): sensor.setup_mqtt_sensor_component(make.Pmqtt, config) -def build_flags(config): - return '-DUSE_ADC_SENSOR' +BUILD_FLAGS = '-DUSE_ADC_SENSOR' diff --git a/esphomeyaml/components/sensor/ads1115.py b/esphomeyaml/components/sensor/ads1115.py index 5572b73e81..3b663232d7 100644 --- a/esphomeyaml/components/sensor/ads1115.py +++ b/esphomeyaml/components/sensor/ads1115.py @@ -59,5 +59,4 @@ def to_code(config): sensor.register_sensor(sensor_, config) -def build_flags(config): - return '-DUSE_ADS1115_SENSOR' +BUILD_FLAGS = '-DUSE_ADS1115_SENSOR' diff --git a/esphomeyaml/components/sensor/bmp085.py b/esphomeyaml/components/sensor/bmp085.py index 50fc5134ce..3dc9b135be 100644 --- a/esphomeyaml/components/sensor/bmp085.py +++ b/esphomeyaml/components/sensor/bmp085.py @@ -31,5 +31,4 @@ def to_code(config): sensor.setup_mqtt_sensor_component(bmp.Pmqtt_pressure, config[CONF_PRESSURE]) -def build_flags(config): - return '-DUSE_BMP085_SENSOR' +BUILD_FLAGS = '-DUSE_BMP085_SENSOR' diff --git a/esphomeyaml/components/sensor/dallas.py b/esphomeyaml/components/sensor/dallas.py index 83bfb6dd44..3bf4127815 100644 --- a/esphomeyaml/components/sensor/dallas.py +++ b/esphomeyaml/components/sensor/dallas.py @@ -34,5 +34,4 @@ def to_code(config): sensor.register_sensor(sensor_, config) -def build_flags(config): - return '-DUSE_DALLAS_SENSOR' +BUILD_FLAGS = '-DUSE_DALLAS_SENSOR' diff --git a/esphomeyaml/components/sensor/dht.py b/esphomeyaml/components/sensor/dht.py index cbccabaab2..9712040c3c 100644 --- a/esphomeyaml/components/sensor/dht.py +++ b/esphomeyaml/components/sensor/dht.py @@ -34,5 +34,4 @@ def to_code(config): sensor.setup_mqtt_sensor_component(dht.Pmqtt_humidity, config[CONF_HUMIDITY]) -def build_flags(config): - return '-DUSE_DHT_SENSOR' +BUILD_FLAGS = '-DUSE_DHT_SENSOR' diff --git a/esphomeyaml/components/sensor/hdc1080.py b/esphomeyaml/components/sensor/hdc1080.py index 24a45f7af2..3b29bf7e24 100644 --- a/esphomeyaml/components/sensor/hdc1080.py +++ b/esphomeyaml/components/sensor/hdc1080.py @@ -28,5 +28,4 @@ def to_code(config): sensor.setup_mqtt_sensor_component(hdc1080.Pmqtt_humidity, config[CONF_HUMIDITY]) -def build_flags(config): - return '-DUSE_HDC1080_SENSOR' +BUILD_FLAGS = '-DUSE_HDC1080_SENSOR' diff --git a/esphomeyaml/components/sensor/htu21d.py b/esphomeyaml/components/sensor/htu21d.py index c532060cc7..3ec4e50b32 100644 --- a/esphomeyaml/components/sensor/htu21d.py +++ b/esphomeyaml/components/sensor/htu21d.py @@ -28,5 +28,4 @@ def to_code(config): sensor.setup_mqtt_sensor_component(htu21d.Pmqtt_humidity, config[CONF_HUMIDITY]) -def build_flags(config): - return '-DUSE_HTU21D_SENSOR' +BUILD_FLAGS = '-DUSE_HTU21D_SENSOR' diff --git a/esphomeyaml/components/sensor/mpu6050.py b/esphomeyaml/components/sensor/mpu6050.py new file mode 100644 index 0000000000..38d63c3861 --- /dev/null +++ b/esphomeyaml/components/sensor/mpu6050.py @@ -0,0 +1,73 @@ +import voluptuous as vol + +import esphomeyaml.config_validation as cv +from esphomeyaml.components import sensor +from esphomeyaml.components.sensor import MQTT_SENSOR_ID_SCHEMA +from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_MQTT_ID, CONF_NAME, CONF_TEMPERATURE, \ + CONF_UPDATE_INTERVAL +from esphomeyaml.helpers import App, Pvariable + +DEPENDENCIES = ['i2c'] + +CONF_ACCEL_X = 'accel_x' +CONF_ACCEL_Y = 'accel_y' +CONF_ACCEL_Z = 'accel_z' +CONF_GYRO_X = 'gyro_x' +CONF_GYRO_Y = 'gyro_y' +CONF_GYRO_Z = 'gyro_z' + +PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ + cv.GenerateID('mpu6050'): cv.register_variable_id, + vol.Optional(CONF_ADDRESS, default=0x68): cv.i2c_address, + vol.Optional(CONF_ACCEL_X): MQTT_SENSOR_ID_SCHEMA, + vol.Optional(CONF_ACCEL_Y): MQTT_SENSOR_ID_SCHEMA, + vol.Optional(CONF_ACCEL_Z): MQTT_SENSOR_ID_SCHEMA, + vol.Optional(CONF_GYRO_X): MQTT_SENSOR_ID_SCHEMA, + vol.Optional(CONF_GYRO_Y): MQTT_SENSOR_ID_SCHEMA, + vol.Optional(CONF_GYRO_Z): MQTT_SENSOR_ID_SCHEMA, + vol.Optional(CONF_TEMPERATURE): MQTT_SENSOR_ID_SCHEMA, + vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period, +}) + + +def to_code(config): + rhs = App.make_mpu6050_sensor(config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL)) + mpu = Pvariable('sensor::MPU6050Component', config[CONF_ID], rhs) + if CONF_ACCEL_X in config: + conf = config[CONF_ACCEL_X] + rhs = mpu.Pmake_accel_x_sensor(conf[CONF_NAME]) + sensor_ = Pvariable('sensor::MPU6050AccelSensor', conf[CONF_MQTT_ID], rhs) + sensor.register_sensor(sensor_, conf) + if CONF_ACCEL_Y in config: + conf = config[CONF_ACCEL_Y] + rhs = mpu.Pmake_accel_y_sensor(conf[CONF_NAME]) + sensor_ = Pvariable('sensor::MPU6050AccelSensor', conf[CONF_MQTT_ID], rhs) + sensor.register_sensor(sensor_, conf) + if CONF_ACCEL_Z in config: + conf = config[CONF_ACCEL_Z] + rhs = mpu.Pmake_accel_z_sensor(conf[CONF_NAME]) + sensor_ = Pvariable('sensor::MPU6050AccelSensor', conf[CONF_MQTT_ID], rhs) + sensor.register_sensor(sensor_, conf) + if CONF_GYRO_X in config: + conf = config[CONF_GYRO_X] + rhs = mpu.Pmake_gyro_x_sensor(conf[CONF_NAME]) + sensor_ = Pvariable('sensor::MPU6050GyroSensor', conf[CONF_MQTT_ID], rhs) + sensor.register_sensor(sensor_, conf) + if CONF_GYRO_Y in config: + conf = config[CONF_GYRO_Y] + rhs = mpu.Pmake_gyro_y_sensor(conf[CONF_NAME]) + sensor_ = Pvariable('sensor::MPU6050GyroSensor', conf[CONF_MQTT_ID], rhs) + sensor.register_sensor(sensor_, conf) + if CONF_GYRO_Z in config: + conf = config[CONF_GYRO_Z] + rhs = mpu.Pmake_gyro_z_sensor(conf[CONF_NAME]) + sensor_ = Pvariable('sensor::MPU6050GyroSensor', conf[CONF_MQTT_ID], rhs) + sensor.register_sensor(sensor_, conf) + if CONF_TEMPERATURE in config: + conf = config[CONF_TEMPERATURE] + rhs = mpu.Pmake_temperature_sensor(conf[CONF_NAME]) + sensor_ = Pvariable('sensor::MPU6050TemperatureSensor', conf[CONF_MQTT_ID], rhs) + sensor.register_sensor(sensor_, conf) + + +BUILD_FLAGS = '-DUSE_MPU6050' diff --git a/esphomeyaml/components/sensor/pulse_counter.py b/esphomeyaml/components/sensor/pulse_counter.py index 38027f9963..3329f3ce25 100644 --- a/esphomeyaml/components/sensor/pulse_counter.py +++ b/esphomeyaml/components/sensor/pulse_counter.py @@ -59,5 +59,4 @@ def to_code(config): sensor.setup_mqtt_sensor_component(make.Pmqtt, config) -def build_flags(config): - return '-DUSE_PULSE_COUNTER_SENSOR' +BUILD_FLAGS = '-DUSE_PULSE_COUNTER_SENSOR' diff --git a/esphomeyaml/components/sensor/ultrasonic.py b/esphomeyaml/components/sensor/ultrasonic.py index f227cd918d..357b771e5f 100644 --- a/esphomeyaml/components/sensor/ultrasonic.py +++ b/esphomeyaml/components/sensor/ultrasonic.py @@ -33,5 +33,4 @@ def to_code(config): sensor.setup_mqtt_sensor_component(make.Pmqtt, config) -def build_flags(config): - return '-DUSE_ULTRASONIC_SENSOR' +BUILD_FLAGS = '-DUSE_ULTRASONIC_SENSOR' diff --git a/esphomeyaml/components/switch/__init__.py b/esphomeyaml/components/switch/__init__.py index 234a4964bb..2ff6f13786 100644 --- a/esphomeyaml/components/switch/__init__.py +++ b/esphomeyaml/components/switch/__init__.py @@ -33,5 +33,4 @@ def register_switch(var, config): setup_mqtt_switch(mqtt_switch, config) -def build_flags(config): - return '-DUSE_SWITCH' +BUILD_FLAGS = '-DUSE_SWITCH' diff --git a/esphomeyaml/components/switch/gpio.py b/esphomeyaml/components/switch/gpio.py index 6b2eaf7294..e37872c6c8 100644 --- a/esphomeyaml/components/switch/gpio.py +++ b/esphomeyaml/components/switch/gpio.py @@ -19,5 +19,4 @@ def to_code(config): switch.setup_mqtt_switch(gpio.Pmqtt, config) -def build_flags(config): - return '-DUSE_GPIO_SWITCH' +BUILD_FLAGS = '-DUSE_GPIO_SWITCH' diff --git a/esphomeyaml/components/switch/ir_transmitter.py b/esphomeyaml/components/switch/ir_transmitter.py index fa5f31907f..d73e4e83dc 100644 --- a/esphomeyaml/components/switch/ir_transmitter.py +++ b/esphomeyaml/components/switch/ir_transmitter.py @@ -92,5 +92,4 @@ def to_code(config): switch.register_switch(switch_, config) -def build_flags(config): - return '-DUSE_IR_TRANSMITTER' +BUILD_FLAGS = '-DUSE_IR_TRANSMITTER' diff --git a/esphomeyaml/components/switch/output.py b/esphomeyaml/components/switch/output.py new file mode 100644 index 0000000000..863e11a3e1 --- /dev/null +++ b/esphomeyaml/components/switch/output.py @@ -0,0 +1,22 @@ +import voluptuous as vol + +import esphomeyaml.config_validation as cv +from esphomeyaml.components import switch +from esphomeyaml.const import CONF_ID, CONF_NAME +from esphomeyaml.helpers import App, get_variable, variable + +PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ + cv.GenerateID('output_switch'): cv.register_variable_id, + vol.Required(CONF_ID): cv.variable_id, +}).extend(switch.MQTT_SWITCH_SCHEMA.schema) + + +def to_code(config): + output = get_variable(config[CONF_ID]) + rhs = App.make_simple_switch(config[CONF_NAME], output) + gpio = variable('Application::MakeSimpleSwitch', config[CONF_ID], rhs) + switch.setup_switch(gpio.Pswitch_, config) + switch.setup_mqtt_switch(gpio.Pmqtt, config) + + +BUILD_FLAGS = '-DUSE_SIMPLE_SWITCH' diff --git a/esphomeyaml/components/switch/restart.py b/esphomeyaml/components/switch/restart.py index a21fc716e2..57f53a4e87 100644 --- a/esphomeyaml/components/switch/restart.py +++ b/esphomeyaml/components/switch/restart.py @@ -15,5 +15,4 @@ def to_code(config): switch.setup_mqtt_switch(restart.Pmqtt, config) -def build_flags(config): - return '-DUSE_RESTART_SWITCH' +BUILD_FLAGS = '-DUSE_RESTART_SWITCH' diff --git a/esphomeyaml/components/switch/shutdown.py b/esphomeyaml/components/switch/shutdown.py new file mode 100644 index 0000000000..0f451ea6e8 --- /dev/null +++ b/esphomeyaml/components/switch/shutdown.py @@ -0,0 +1,19 @@ +import esphomeyaml.config_validation as cv +from esphomeyaml.components import switch +from esphomeyaml.const import CONF_ID, CONF_NAME +from esphomeyaml.helpers import App, variable + +PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ + cv.GenerateID('shutdown_switch'): cv.register_variable_id, +}).extend(switch.MQTT_SWITCH_SCHEMA.schema) + + +def to_code(config): + rhs = App.make_shutdown_switch(config[CONF_NAME]) + shutdown = variable('Application::MakeShutdownSwitch', config[CONF_ID], + rhs) + switch.setup_switch(shutdown.Pshutdown, config) + switch.setup_mqtt_switch(shutdown.Pmqtt, config) + + +BUILD_FLAGS = '-DUSE_SHUTDOWN_SWITCH' diff --git a/esphomeyaml/components/web_server.py b/esphomeyaml/components/web_server.py index 3eff1b8160..486ebfdc85 100644 --- a/esphomeyaml/components/web_server.py +++ b/esphomeyaml/components/web_server.py @@ -25,5 +25,4 @@ def to_code(config): add(web_server.set_js_url(config[CONF_JS_URL])) -def build_flags(config): - return '-DUSE_WEB_SERVER' +BUILD_FLAGS = '-DUSE_WEB_SERVER' diff --git a/esphomeyaml/config.py b/esphomeyaml/config.py index 75b789f901..e7a4850c4f 100644 --- a/esphomeyaml/config.py +++ b/esphomeyaml/config.py @@ -190,6 +190,9 @@ def _format_config_error(ex, domain, config): else: message += u'{}.'.format(humanize_error(config, ex)) + if isinstance(config, list): + return message + domain_config = config.get(domain, config) message += u" (See {}, line {}). ".format( getattr(domain_config, '__config_file__', '?'), @@ -203,6 +206,7 @@ def load_config(path): config = yaml_util.load_yaml(path) except OSError: raise ESPHomeYAMLError(u"Could not read configuration file at {}".format(path)) + core.RAW_CONFIG = config if CONF_ESPHOMEYAML not in config: raise ESPHomeYAMLError(u"No esphomeyaml section in config") diff --git a/esphomeyaml/config_validation.py b/esphomeyaml/config_validation.py index 8b9f4fd9fc..c1c9f1b211 100644 --- a/esphomeyaml/config_validation.py +++ b/esphomeyaml/config_validation.py @@ -3,6 +3,7 @@ from __future__ import print_function import logging +import re from datetime import timedelta import voluptuous as vol @@ -192,30 +193,65 @@ time_period_dict = vol.All( lambda value: timedelta(**value)) -def time_period_str(value): - """Validate and transform time offset.""" +def time_period_str_colon(value): + """Validate and transform time offset with format HH:MM[:SS].""" if isinstance(value, int): - raise vol.Invalid("Make sure you wrap time values in quotes") - elif not isinstance(value, (str, unicode)): + raise vol.Invalid('Make sure you wrap time values in quotes') + elif not isinstance(value, str): raise vol.Invalid(TIME_PERIOD_ERROR.format(value)) - value = unicode(value) - if value.endswith(u'ms'): - return vol.Coerce(int)(value[:-2]) - elif value.endswith(u's'): - return vol.Coerce(float)(value[:-1]) * 1000 - elif value.endswith(u'min'): - return vol.Coerce(float)(value[:-3]) * 1000 * 60 - elif value.endswith(u'h'): - return vol.Coerce(float)(value[:-1]) * 1000 * 60 * 60 - raise vol.Invalid(TIME_PERIOD_ERROR.format(value)) + negative_offset = False + if value.startswith('-'): + negative_offset = True + value = value[1:] + elif value.startswith('+'): + value = value[1:] - -def time_period_milliseconds(value): try: - return timedelta(milliseconds=int(value)) - except (ValueError, TypeError): - raise vol.Invalid('Expected milliseconds, got {}'.format(value)) + parsed = [int(x) for x in value.split(':')] + except ValueError: + raise vol.Invalid(TIME_PERIOD_ERROR.format(value)) + + if len(parsed) == 2: + hour, minute = parsed + second = 0 + elif len(parsed) == 3: + hour, minute, second = parsed + else: + raise vol.Invalid(TIME_PERIOD_ERROR.format(value)) + + offset = timedelta(hours=hour, minutes=minute, seconds=second) + + if negative_offset: + offset *= -1 + + return offset + + +def time_period_str_unit(value): + """Validate and transform time period with time unit and integer value.""" + if isinstance(value, int): + value = str(value) + elif not isinstance(value, str): + raise vol.Invalid("Expected string for time period with unit.") + + unit_to_kwarg = { + 'ms': 'milliseconds', + 's': 'seconds', + 'sec': 'seconds', + 'min': 'minutes', + 'h': 'hours', + 'd': 'days', + } + + match = re.match(r"^([-+]?\d+)\s*(\w*)$", value) + + if match is None or match.group(2) not in unit_to_kwarg: + raise vol.Invalid(u"Expected time period with unit, " + u"got {}".format(value)) + + kwarg = unit_to_kwarg[match.group(2)] + return timedelta(**{kwarg: int(match.group(1))}) def time_period_to_milliseconds(value): @@ -223,11 +259,18 @@ def time_period_to_milliseconds(value): return value if isinstance(value, float): return int(value) - return value / timedelta(milliseconds=1) + return int(value.total_seconds() * 1000) -time_period = vol.All(vol.Any(time_period_str, timedelta, time_period_dict, - time_period_milliseconds), time_period_to_milliseconds) +def time_period_to_seconds(value): + if value / 1000 != value // 1000: + raise vol.Invalid("Fractions of seconds are not supported here.") + return value / 1000 + + +time_period = vol.All(vol.Any(time_period_str_colon, time_period_str_unit, timedelta, + time_period_dict), + time_period_to_milliseconds) positive_time_period = vol.All(time_period, vol.Range(min=0)) positive_not_null_time_period = vol.All(time_period, vol.Range(min=0, min_included=False)) @@ -294,17 +337,62 @@ def ipv4(value): return IPAddress(*parts_) -def publish_topic(value): - value = string_strict(value) - if value.endswith('/'): - raise vol.Invalid("Publish topic can't end with '/'") - if '+' in value or '#' in value: - raise vol.Invalid("Publish topic can't contain '+' or '#'") +def _valid_topic(value): + """Validate that this is a valid topic name/filter.""" + if isinstance(value, dict): + raise vol.Invalid("Can't use dictionary with topic") + value = string(value) + try: + raw_value = value.encode('utf-8') + except UnicodeError: + raise vol.Invalid("MQTT topic name/filter must be valid UTF-8 string.") + if not raw_value: + raise vol.Invalid("MQTT topic name/filter must not be empty.") + if len(raw_value) > 65535: + raise vol.Invalid("MQTT topic name/filter must not be longer than " + "65535 encoded bytes.") + if '\0' in value: + raise vol.Invalid("MQTT topic name/filter must not contain null " + "character.") return value -subscribe_topic = string_strict # TODO improve this -mqtt_payload = string # TODO improve this +def subscribe_topic(value): + """Validate that we can subscribe using this MQTT topic.""" + value = _valid_topic(value) + for i in (i for i, c in enumerate(value) if c == '+'): + if (i > 0 and value[i - 1] != '/') or \ + (i < len(value) - 1 and value[i + 1] != '/'): + raise vol.Invalid("Single-level wildcard must occupy an entire " + "level of the filter") + + index = value.find('#') + if index != -1: + if index != len(value) - 1: + # If there are multiple wildcards, this will also trigger + raise vol.Invalid("Multi-level wildcard must be the last " + "character in the topic filter.") + if len(value) > 1 and value[index - 1] != '/': + raise vol.Invalid("Multi-level wildcard must be after a topic " + "level separator.") + + return value + + +def publish_topic(value): + """Validate that we can publish using this MQTT topic.""" + value = _valid_topic(value) + if '+' in value or '#' in value: + raise vol.Invalid("Wildcards can not be used in topic names") + return value + + +def mqtt_payload(value): + if value is None: + return '' + return string(value) + + uint8_t = vol.All(int_, vol.Range(min=0, max=255)) uint16_t = vol.All(int_, vol.Range(min=0, max=65535)) uint32_t = vol.All(int_, vol.Range(min=0, max=4294967295)) diff --git a/esphomeyaml/const.py b/esphomeyaml/const.py index 52d0453ea9..565d263273 100644 --- a/esphomeyaml/const.py +++ b/esphomeyaml/const.py @@ -161,6 +161,9 @@ CONF_AP = 'ap' CONF_CSS_URL = 'css_url' CONF_JS_URL = 'js_url' CONF_SSL_FINGERPRINTS = 'ssl_fingerprints' +CONF_PCF8575 = 'pcf8575' +CONF_SCAN = 'scan' +CONF_KEEPALIVE = 'keepalive' ESP32_BOARDS = [ 'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', diff --git a/esphomeyaml/core.py b/esphomeyaml/core.py index 087e4ebcaf..2e696c285a 100644 --- a/esphomeyaml/core.py +++ b/esphomeyaml/core.py @@ -22,3 +22,4 @@ CONFIG_PATH = None SIMPLIFY = True ESP_PLATFORM = '' BOARD = '' +RAW_CONFIG = None diff --git a/esphomeyaml/helpers.py b/esphomeyaml/helpers.py index dc8c993142..bc69279f6a 100644 --- a/esphomeyaml/helpers.py +++ b/esphomeyaml/helpers.py @@ -370,6 +370,18 @@ def get_gpio_pin_number(conf): def exp_gpio_pin_(obj, conf, default_mode): if isinstance(conf, int): return conf + + if 'pcf8574' in conf: + hub = get_variable(conf['pcf8574']) + if default_mode == u'INPUT': + return hub.make_input_pin(conf[CONF_NUMBER], + RawExpression('PCF8574_' + conf[CONF_MODE]), + conf[CONF_INVERTED]) + elif default_mode == u'OUTPUT': + return hub.make_output_pin(conf[CONF_NUMBER], conf[CONF_INVERTED]) + else: + raise ESPHomeYAMLError(u"Unknown default mode {}".format(default_mode)) + if conf.get(CONF_INVERTED) is None: return obj(conf[CONF_NUMBER], conf.get(CONF_MODE)) return obj(conf[CONF_NUMBER], RawExpression(conf.get(CONF_MODE, default_mode)), diff --git a/esphomeyaml/pins.py b/esphomeyaml/pins.py index f39fbe5ff4..99ccfa97f1 100644 --- a/esphomeyaml/pins.py +++ b/esphomeyaml/pins.py @@ -5,7 +5,7 @@ import voluptuous as vol import esphomeyaml.config_validation as cv from esphomeyaml import core from esphomeyaml.const import ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_NUMBER, CONF_MODE, \ - CONF_INVERTED + CONF_INVERTED, CONF_ID, CONF_PCF8575 _LOGGER = logging.getLogger(__name__) @@ -72,7 +72,7 @@ def _translate_pin(value): except ValueError: pass if value.startswith('GPIO'): - return vol.Coerce(int)(value[len('GPIO'):]) + return vol.Coerce(int)(value[len('GPIO'):].strip()) if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: if value in ESP32_PINS: return ESP32_PINS[value] @@ -80,7 +80,7 @@ def _translate_pin(value): raise vol.Invalid(u"ESP32: Unknown board {} with unknown " u"pin {}.".format(core.BOARD, value)) if value not in ESP32_BOARD_TO_PINS[core.BOARD]: - raise vol.Invalid(u"ESP32: Board {} doesn't have" + raise vol.Invalid(u"ESP32: Board {} doesn't have " u"pin {}".format(core.BOARD, value)) return ESP32_BOARD_TO_PINS[core.BOARD][value] elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: @@ -90,7 +90,7 @@ def _translate_pin(value): raise vol.Invalid(u"ESP8266: Unknown board {} with unknown " u"pin {}.".format(core.BOARD, value)) if value not in ESP8266_BOARD_TO_PINS[core.BOARD]: - raise vol.Invalid(u"ESP8266: Board {} doesn't have" + raise vol.Invalid(u"ESP8266: Board {} doesn't have " u"pin {}".format(core.BOARD, value)) return ESP8266_BOARD_TO_PINS[core.BOARD][value] raise vol.Invalid(u"Invalid ESP platform.") @@ -179,19 +179,57 @@ def pin_mode(value): raise vol.Invalid(u"Invalid ESP platform.") -GPIO_PIN_SCHEMA = vol.Schema({ - vol.Required(CONF_NUMBER): gpio_pin, - vol.Required(CONF_MODE): pin_mode, - vol.Optional(CONF_INVERTED): cv.boolean, -}) +def pcf8574_pin(value, default_mode): + if 'pcf8574' not in core.RAW_CONFIG: + raise vol.Invalid("PCF8574 not loaded, ignore this.") -GPIO_OUTPUT_PIN_SCHEMA = vol.Any(output_pin, vol.Schema({ + if isinstance(value, (str, unicode)): + value = {CONF_NUMBER: value} + + if not isinstance(value, dict) or not isinstance(value.get(CONF_NUMBER), (str, unicode)) or \ + value[CONF_NUMBER].count('.') != 1: + raise vol.Invalid("Not PCF8574 pin") + + pcf_id, pin = value[CONF_NUMBER].split('.') + pin = vol.Coerce(int)(pin) + + pcf_conf = cv.ensure_list(core.RAW_CONFIG['pcf8574']) + pcf = next((conf for conf in pcf_conf if conf[CONF_ID] == pcf_id), None) + if pcf is None: + raise vol.Invalid("Unknown PCF8574 id: {}".format(pcf_id)) + + if pcf.get(CONF_PCF8575, False): + pin = vol.Range(min=0, max=15)(pin) + else: + pin = vol.Range(min=0, max=7)(pin) + + mode = vol.All(vol.Coerce(str), vol.Upper)(value.get(CONF_MODE, default_mode)) + if mode not in ['INPUT', 'INPUT_PULLUP', 'OUTPUT']: + raise vol.Invalid("Invalid pin mode for PCF8575: {}".format(mode)) + + return { + 'pcf8574': pcf[CONF_ID], + CONF_NUMBER: pin, + CONF_INVERTED: value.get(CONF_INVERTED, False), + CONF_MODE: mode + } + + +def pcf8574_output_pin(value): + return pcf8574_pin(value, 'OUTPUT') + + +def pcf8574_input_pin(value): + return pcf8574_pin(value, 'INPUT') + + +GPIO_OUTPUT_PIN_SCHEMA = vol.Any(output_pin, pcf8574_output_pin, vol.Schema({ vol.Required(CONF_NUMBER): output_pin, vol.Optional(CONF_MODE): pin_mode, vol.Optional(CONF_INVERTED): cv.boolean, })) -GPIO_INPUT_PIN_SCHEMA = vol.Any(input_pin, vol.Schema({ +GPIO_INPUT_PIN_SCHEMA = vol.Any(input_pin, pcf8574_input_pin, vol.Schema({ vol.Required(CONF_NUMBER): input_pin, vol.Optional(CONF_MODE): pin_mode, vol.Optional(CONF_INVERTED): cv.boolean, diff --git a/esphomeyaml/writer.py b/esphomeyaml/writer.py index 24053715e7..769dbc628c 100644 --- a/esphomeyaml/writer.py +++ b/esphomeyaml/writer.py @@ -4,6 +4,7 @@ import codecs import errno import os +from esphomeyaml import core from esphomeyaml.config import iter_components from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_NAME, \ CONF_PLATFORM, CONF_USE_BUILD_FLAGS, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 @@ -50,7 +51,7 @@ platform = {platform} board = {board} framework = arduino lib_deps = - {esphomeyaml_uri} + {lib_deps} ${{common.lib_deps}} build_flags = {build_flags} @@ -68,7 +69,9 @@ def get_build_flags(config, key): for _, component, conf in iter_components(config): if not hasattr(component, key): continue - flags = getattr(component, key)(conf) + flags = getattr(component, key) + if callable(flags): + flags = flags(conf) if flags is None: continue if isinstance(flags, (str, unicode)): @@ -85,12 +88,12 @@ def get_ini_content(config): u'env': config[CONF_ESPHOMEYAML][CONF_NAME], u'platform': platform, u'board': config[CONF_ESPHOMEYAML][CONF_BOARD], - u'esphomeyaml_uri': config[CONF_ESPHOMEYAML][CONF_LIBRARY_URI], u'build_flags': u'', } build_flags = set() if config[CONF_ESPHOMEYAML][CONF_USE_BUILD_FLAGS]: build_flags |= get_build_flags(config, 'build_flags') + build_flags |= get_build_flags(config, 'BUILD_FLAGS') build_flags.add(u"-DESPHOMEYAML_USE") build_flags |= get_build_flags(config, 'required_build_flags') @@ -98,6 +101,31 @@ def get_ini_content(config): build_flags = sorted(list(build_flags)) if build_flags: options[u'build_flags'] = u'\n '.join(build_flags) + + lib_deps = set() + lib_deps.add(config[CONF_ESPHOMEYAML][CONF_LIBRARY_URI]) + if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: + lib_deps |= { + 'ArduinoOTA', + 'Update', + 'ESPmDNS', + 'Wire', + 'FS', + 'Preferences', + + } + elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: + lib_deps |= { + 'ESP8266WiFi', + 'Wire', + 'Hash', + 'ESP8266mDNS', + 'ArduinoOTA', + } + else: + raise ESPHomeYAMLError("Unsupported platform {}".format(core.ESP_PLATFORM)) + options[u'lib_deps'] = u'\n '.join(sorted(list(lib_deps))) + return INI_CONTENT_FORMAT.format(**options)