mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	| @@ -6,19 +6,16 @@ import os | ||||
| import random | ||||
| import sys | ||||
|  | ||||
| from esphomeyaml import helpers, mqtt, writer, yaml_util, wizard | ||||
| from esphomeyaml.config import add_component_task, read_config | ||||
| from esphomeyaml.const import CONF_ESPHOMEYAML, CONF_HOSTNAME, CONF_MANUAL_IP, CONF_NAME, \ | ||||
|     CONF_STATIC_IP, \ | ||||
|     CONF_WIFI, CONF_LOGGER, CONF_BAUD_RATE | ||||
| from esphomeyaml.helpers import AssignmentExpression, RawStatement, _EXPRESSIONS, add, \ | ||||
|     get_variable, indent, quote, statement, color | ||||
| from esphomeyaml import core, mqtt, wizard, writer, yaml_util, const | ||||
| from esphomeyaml.config import core_to_code, get_component, iter_components, read_config | ||||
| from esphomeyaml.const import CONF_BAUD_RATE, CONF_ESPHOMEYAML, CONF_HOSTNAME, CONF_LOGGER, \ | ||||
|     CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI | ||||
| from esphomeyaml.helpers import AssignmentExpression, RawStatement, _EXPRESSIONS, add, add_task, \ | ||||
|     color, get_variable, indent, quote, statement, Expression | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ota', 'mqtt', 'i2c'] | ||||
|  | ||||
| CONFIG_PATH = None | ||||
| PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ota', 'mqtt', 'web_server', 'i2c'] | ||||
|  | ||||
|  | ||||
| def get_name(config): | ||||
| @@ -26,7 +23,7 @@ def get_name(config): | ||||
|  | ||||
|  | ||||
| def get_base_path(config): | ||||
|     return os.path.join(os.path.dirname(CONFIG_PATH), get_name(config)) | ||||
|     return os.path.join(os.path.dirname(core.CONFIG_PATH), get_name(config)) | ||||
|  | ||||
|  | ||||
| def discover_serial_ports(): | ||||
| @@ -47,8 +44,6 @@ def discover_serial_ports(): | ||||
|  | ||||
|     if not result: | ||||
|         return None | ||||
|     if len(result) == 1: | ||||
|         return result[0] | ||||
|     print(u"Found multiple serial port options, please choose one:") | ||||
|     for i, (res, desc) in enumerate(zip(result, descs)): | ||||
|         print(u"  [{}] {} ({})".format(i, res, desc)) | ||||
| @@ -107,18 +102,24 @@ def run_miniterm(config, port): | ||||
|  | ||||
| def write_cpp(config): | ||||
|     _LOGGER.info("Generating C++ source...") | ||||
|  | ||||
|     add_task(core_to_code, config[CONF_ESPHOMEYAML]) | ||||
|     for domain in PRE_INITIALIZE: | ||||
|         if domain == CONF_ESPHOMEYAML: | ||||
|             continue | ||||
|         if domain in config: | ||||
|             add_component_task(domain, config[domain]) | ||||
|             add_task(get_component(domain).to_code, config[domain]) | ||||
|  | ||||
|     # Clear queue | ||||
|     get_variable(None) | ||||
|     add(RawStatement('')) | ||||
|  | ||||
|     for domain, conf in config.iteritems(): | ||||
|     for domain, component, conf in iter_components(config): | ||||
|         if domain in PRE_INITIALIZE: | ||||
|             continue | ||||
|         add_component_task(domain, conf) | ||||
|         if not hasattr(component, 'to_code'): | ||||
|             continue | ||||
|         add_task(component.to_code, conf) | ||||
|  | ||||
|     # Clear queue | ||||
|     get_variable(None) | ||||
| @@ -127,7 +128,10 @@ def write_cpp(config): | ||||
|  | ||||
|     all_code = [] | ||||
|     for exp in _EXPRESSIONS: | ||||
|         if helpers.SIMPLIFY and isinstance(exp, AssignmentExpression) and exp.obj.usages == 0: | ||||
|         if core.SIMPLIFY: | ||||
|             if isinstance(exp, Expression) and not exp.required: | ||||
|                 continue | ||||
|             if isinstance(exp, AssignmentExpression) and not exp.obj.required: | ||||
|                 exp = exp.rhs | ||||
|         all_code.append(unicode(statement(exp))) | ||||
|  | ||||
| @@ -211,8 +215,6 @@ def setup_log(): | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|     global CONFIG_PATH | ||||
|  | ||||
|     setup_log() | ||||
|  | ||||
|     parser = argparse.ArgumentParser(prog='esphomeyaml') | ||||
| @@ -260,13 +262,17 @@ def main(): | ||||
|     subparsers.add_parser('wizard', help="A helpful setup wizard that will guide " | ||||
|                                          "you through setting up esphomeyaml.") | ||||
|  | ||||
|     subparsers.add_parser('mqtt-fingerprint', help="Get the SSL fingerprint from a MQTT broker.") | ||||
|     subparsers.add_parser('version', help="Print the esphomeyaml version and exit.") | ||||
|  | ||||
|     args = parser.parse_args() | ||||
|  | ||||
|     if args.command == 'wizard': | ||||
|         return wizard.wizard(args.configuration) | ||||
|  | ||||
|     CONFIG_PATH = args.configuration | ||||
|     config = read_config(CONFIG_PATH) | ||||
|     core.CONFIG_PATH = args.configuration | ||||
|  | ||||
|     config = read_config(core.CONFIG_PATH) | ||||
|     if config is None: | ||||
|         return 1 | ||||
|  | ||||
| @@ -294,6 +300,8 @@ def main(): | ||||
|         return show_logs(config, args, port) | ||||
|     elif args.command == 'clean-mqtt': | ||||
|         return clean_mqtt(config, args) | ||||
|     elif args.command == 'mqtt-fingerprint': | ||||
|         return mqtt.get_fingerprint(config) | ||||
|     elif args.command == 'run': | ||||
|         exit_code = write_cpp(config) | ||||
|         if exit_code != 0: | ||||
| @@ -302,14 +310,17 @@ def main(): | ||||
|         if exit_code != 0: | ||||
|             return exit_code | ||||
|         _LOGGER.info(u"Successfully compiled program.") | ||||
|         if args.no_logs: | ||||
|             return 0 | ||||
|         port = args.upload_port or discover_serial_ports() | ||||
|         exit_code = upload_program(config, args, port) | ||||
|         if exit_code != 0: | ||||
|             return exit_code | ||||
|         _LOGGER.info(u"Successfully uploaded program.") | ||||
|         if args.no_logs: | ||||
|             return 0 | ||||
|         return show_logs(config, args, port) | ||||
|     elif args.command == 'version': | ||||
|         print(u"Version: {}".format(const.__version__)) | ||||
|         return 0 | ||||
|     print(u"Unknown command {}".format(args.command)) | ||||
|     return 1 | ||||
|  | ||||
|   | ||||
| @@ -35,3 +35,7 @@ def to_code(config): | ||||
|         ads1115 = Pvariable(ADS1115_COMPONENT_CLASS, conf[CONF_ID], rhs) | ||||
|         if CONF_RATE in conf: | ||||
|             add(ads1115.set_rate(RawExpression(RATES[conf[CONF_RATE]]))) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_ADS1115_SENSOR' | ||||
|   | ||||
| @@ -4,10 +4,6 @@ import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_INVERTED | ||||
| from esphomeyaml.helpers import add, setup_mqtt_component | ||||
|  | ||||
| PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | ||||
|     vol.Optional(CONF_INVERTED): cv.boolean, | ||||
| }) | ||||
|  | ||||
| DEVICE_CLASSES = [ | ||||
|     '', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas', | ||||
|     'heat', 'light', 'lock', 'moisture', 'motion', 'moving', 'occupancy', | ||||
| @@ -17,13 +13,27 @@ DEVICE_CLASSES = [ | ||||
|  | ||||
| DEVICE_CLASSES_MSG = "Unknown device class. Must be one of {}".format(', '.join(DEVICE_CLASSES)) | ||||
|  | ||||
| MQTT_BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({ | ||||
| PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | ||||
|     vol.Optional(CONF_INVERTED): cv.boolean, | ||||
|     vol.Optional(CONF_DEVICE_CLASS): vol.All(vol.Lower, | ||||
|                                              vol.Any(*DEVICE_CLASSES, msg=DEVICE_CLASSES_MSG)), | ||||
| }) | ||||
|  | ||||
| MQTT_BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({ | ||||
|  | ||||
| def setup_mqtt_binary_sensor(obj, config, skip_device_class=False): | ||||
|     if not skip_device_class and CONF_DEVICE_CLASS in config: | ||||
| }) | ||||
|  | ||||
|  | ||||
| def setup_binary_sensor(obj, config): | ||||
|     if CONF_DEVICE_CLASS in config: | ||||
|         add(obj.set_device_class(config[CONF_DEVICE_CLASS])) | ||||
|     if CONF_INVERTED in config: | ||||
|         add(obj.set_inverted(config[CONF_INVERTED])) | ||||
|  | ||||
|  | ||||
| def setup_mqtt_binary_sensor(obj, config): | ||||
|     setup_mqtt_component(obj, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_BINARY_SENSOR' | ||||
|   | ||||
| @@ -3,7 +3,7 @@ import voluptuous as vol | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.components import binary_sensor | ||||
| from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INVERTED, CONF_NAME, CONF_PIN | ||||
| from esphomeyaml.const import CONF_ID, CONF_INVERTED, CONF_NAME, CONF_PIN | ||||
| from esphomeyaml.helpers import App, add, exp_gpio_input_pin, variable | ||||
|  | ||||
| PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ | ||||
| @@ -13,9 +13,13 @@ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_gpio_binary_sensor(exp_gpio_input_pin(config[CONF_PIN]), | ||||
|                                       config[CONF_NAME], config.get(CONF_DEVICE_CLASS)) | ||||
|     gpio = variable('Application::SimpleBinarySensor', config[CONF_ID], rhs) | ||||
|     rhs = App.make_gpio_binary_sensor(config[CONF_NAME], exp_gpio_input_pin(config[CONF_PIN])) | ||||
|     gpio = variable('Application::MakeGPIOBinarySensor', config[CONF_ID], rhs) | ||||
|     if CONF_INVERTED in config: | ||||
|         add(gpio.Pgpio.set_inverted(config[CONF_INVERTED])) | ||||
|     binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config, skip_device_class=True) | ||||
|     binary_sensor.setup_binary_sensor(gpio.Pgpio, config) | ||||
|     binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_GPIO_BINARY_SENSOR' | ||||
|   | ||||
| @@ -1,7 +1,9 @@ | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import binary_sensor | ||||
| from esphomeyaml.const import CONF_ID, CONF_NAME | ||||
| from esphomeyaml.helpers import App, Pvariable | ||||
| from esphomeyaml.helpers import App, variable | ||||
|  | ||||
| DEPENDENCIES = ['mqtt'] | ||||
|  | ||||
| PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID('status_binary_sensor'): cv.register_variable_id, | ||||
| @@ -10,5 +12,10 @@ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_status_binary_sensor(config[CONF_NAME]) | ||||
|     gpio = Pvariable('binary_sensor::MQTTBinarySensorComponent', config[CONF_ID], rhs) | ||||
|     binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config) | ||||
|     status = variable('Application::MakeStatusBinarySensor', config[CONF_ID], rhs) | ||||
|     binary_sensor.setup_binary_sensor(status.Pstatus, config) | ||||
|     binary_sensor.setup_mqtt_binary_sensor(status.Pmqtt, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_STATUS_BINARY_SENSOR' | ||||
|   | ||||
| @@ -18,3 +18,7 @@ def to_code(config): | ||||
|     for conf in config: | ||||
|         rhs = App.make_dallas_component(conf[CONF_PIN], conf.get(CONF_UPDATE_INTERVAL)) | ||||
|         Pvariable(DALLAS_COMPONENT_CLASS, conf[CONF_ID], rhs) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_DALLAS_SENSOR' | ||||
|   | ||||
							
								
								
									
										15
									
								
								esphomeyaml/components/debug.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								esphomeyaml/components/debug.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| from esphomeyaml.helpers import App, add | ||||
|  | ||||
| DEPENDENCIES = ['logger'] | ||||
|  | ||||
| CONFIG_SCHEMA = vol.Schema({}) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     add(App.make_debug_component()) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_DEBUG_COMPONENT' | ||||
							
								
								
									
										42
									
								
								esphomeyaml/components/deep_sleep.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								esphomeyaml/components/deep_sleep.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| from esphomeyaml import config_validation as cv, pins | ||||
| from esphomeyaml.const import CONF_ID, CONF_RUN_CYCLES, CONF_RUN_DURATION, CONF_SLEEP_DURATION, \ | ||||
|     CONF_WAKEUP_PIN | ||||
| from esphomeyaml.helpers import App, Pvariable, add, exp_gpio_input_pin | ||||
|  | ||||
|  | ||||
| def validate_pin_number(value): | ||||
|     valid_pins = [0, 2, 4, 12, 13, 14, 15, 25, 26, 27, 32, 39] | ||||
|     if value not in valid_pins: | ||||
|         raise vol.Invalid(u"Only pins {} support wakeup" | ||||
|                           u"".format(', '.join(str(x) for x in valid_pins))) | ||||
|     return value | ||||
|  | ||||
|  | ||||
| CONFIG_SCHEMA = vol.Schema({ | ||||
|     cv.GenerateID('deep_sleep'): cv.register_variable_id, | ||||
|     vol.Optional(CONF_SLEEP_DURATION): cv.positive_time_period, | ||||
|     vol.Optional(CONF_WAKEUP_PIN): vol.All(cv.only_on_esp32, pins.GPIO_INPUT_PIN_SCHEMA, | ||||
|                                            pins.schema_validate_number(validate_pin_number)), | ||||
|     vol.Optional(CONF_RUN_CYCLES): cv.positive_int, | ||||
|     vol.Optional(CONF_RUN_DURATION): cv.positive_time_period, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_deep_sleep_component() | ||||
|     deep_sleep = Pvariable('DeepSleepComponent', config[CONF_ID], rhs) | ||||
|     if CONF_SLEEP_DURATION in config: | ||||
|         add(deep_sleep.set_sleep_duration(config[CONF_SLEEP_DURATION])) | ||||
|     if CONF_WAKEUP_PIN in config: | ||||
|         pin = exp_gpio_input_pin(config[CONF_WAKEUP_PIN]) | ||||
|         add(deep_sleep.set_wakeup_pin(pin)) | ||||
|     if CONF_RUN_CYCLES in config: | ||||
|         add(deep_sleep.set_run_cycles(config[CONF_RUN_CYCLES])) | ||||
|     if CONF_RUN_DURATION in config: | ||||
|         add(deep_sleep.set_run_duration(config[CONF_RUN_DURATION])) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_DEEP_SLEEP' | ||||
| @@ -21,3 +21,7 @@ def setup_mqtt_fan(obj, config): | ||||
|     if CONF_SPEED_COMMAND_TOPIC in config: | ||||
|         add(obj.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC])) | ||||
|     setup_mqtt_component(obj, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_FAN' | ||||
|   | ||||
| @@ -15,7 +15,7 @@ PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({ | ||||
| def to_code(config): | ||||
|     output = get_variable(config[CONF_OUTPUT]) | ||||
|     rhs = App.make_fan(config[CONF_NAME]) | ||||
|     fan_struct = variable('Application::FanStruct', config[CONF_ID], rhs) | ||||
|     fan_struct = variable('Application::MakeFan', config[CONF_ID], rhs) | ||||
|     add(fan_struct.Poutput.set_binary(output)) | ||||
|     if CONF_OSCILLATION_OUTPUT in config: | ||||
|         oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT]) | ||||
|   | ||||
| @@ -24,7 +24,7 @@ PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({ | ||||
| def to_code(config): | ||||
|     output = get_variable(config[CONF_OUTPUT]) | ||||
|     rhs = App.make_fan(config[CONF_NAME]) | ||||
|     fan_struct = variable('Application::FanStruct', config[CONF_ID], rhs) | ||||
|     fan_struct = variable('Application::MakeFan', config[CONF_ID], rhs) | ||||
|     if CONF_SPEED in config: | ||||
|         speeds = config[CONF_SPEED] | ||||
|         add(fan_struct.Poutput.set_speed(output, 0.0, | ||||
|   | ||||
| @@ -14,3 +14,7 @@ CONFIG_SCHEMA = vol.Schema({ | ||||
|  | ||||
| def to_code(config): | ||||
|     add(App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_FREQUENCY))) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_I2C' | ||||
|   | ||||
| @@ -21,3 +21,7 @@ def to_code(config): | ||||
|         pin = exp_gpio_output_pin(conf[CONF_PIN]) | ||||
|         rhs = App.make_ir_transmitter(pin, conf.get(CONF_CARRIER_DUTY_PERCENT)) | ||||
|         Pvariable(IR_TRANSMITTER_COMPONENT_CLASS, conf[CONF_ID], rhs) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_IR_TRANSMITTER' | ||||
|   | ||||
| @@ -1,13 +1,16 @@ | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH | ||||
| from esphomeyaml.helpers import add, setup_mqtt_component | ||||
| from esphomeyaml.helpers import add | ||||
|  | ||||
| PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
| }).extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA.schema) | ||||
|  | ||||
|  | ||||
| def setup_mqtt_light_component(obj, config): | ||||
| def setup_light_component(obj, config): | ||||
|     if CONF_DEFAULT_TRANSITION_LENGTH in config: | ||||
|         add(obj.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH])) | ||||
|     setup_mqtt_component(obj, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_LIGHT' | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import voluptuous as vol | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import light | ||||
| from esphomeyaml.const import CONF_ID, CONF_NAME, CONF_OUTPUT | ||||
| from esphomeyaml.helpers import App, get_variable, variable | ||||
| from esphomeyaml.helpers import App, get_variable, variable, setup_mqtt_component | ||||
|  | ||||
| PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID('binary_light'): cv.register_variable_id, | ||||
| @@ -15,5 +15,6 @@ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||
| def to_code(config): | ||||
|     output = get_variable(config[CONF_OUTPUT]) | ||||
|     rhs = App.make_binary_light(config[CONF_NAME], output) | ||||
|     light_struct = variable('Application::LightStruct', config[CONF_ID], rhs) | ||||
|     light.setup_mqtt_light_component(light_struct.Pmqtt, config) | ||||
|     light_struct = variable('Application::MakeLight', config[CONF_ID], rhs) | ||||
|     setup_mqtt_component(light_struct.Pmqtt, config) | ||||
|     light.setup_light_component(light_struct.Pstate, config) | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import light | ||||
| from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, \ | ||||
|     CONF_NAME, CONF_OUTPUT | ||||
| from esphomeyaml.helpers import App, add, get_variable, variable | ||||
| from esphomeyaml.helpers import App, add, get_variable, variable, setup_mqtt_component | ||||
|  | ||||
| PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID('monochromatic_light'): cv.register_variable_id, | ||||
| @@ -17,7 +17,8 @@ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||
| def to_code(config): | ||||
|     output = get_variable(config[CONF_OUTPUT]) | ||||
|     rhs = App.make_monochromatic_light(config[CONF_NAME], output) | ||||
|     light_struct = variable('Application::LightStruct', config[CONF_ID], rhs) | ||||
|     light_struct = variable('Application::MakeLight', config[CONF_ID], rhs) | ||||
|     if CONF_GAMMA_CORRECT in config: | ||||
|         add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT])) | ||||
|     light.setup_mqtt_light_component(light_struct.Pmqtt, config) | ||||
|     setup_mqtt_component(light_struct.Pmqtt, config) | ||||
|     light.setup_light_component(light_struct.Pstate, config) | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import light | ||||
| from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ | ||||
|     CONF_GREEN, CONF_ID, CONF_NAME, CONF_RED | ||||
| from esphomeyaml.helpers import App, add, get_variable, variable | ||||
| from esphomeyaml.helpers import App, add, get_variable, variable, setup_mqtt_component | ||||
|  | ||||
| PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID('rgb_light'): cv.register_variable_id, | ||||
| @@ -21,7 +21,8 @@ def to_code(config): | ||||
|     green = get_variable(config[CONF_GREEN]) | ||||
|     blue = get_variable(config[CONF_BLUE]) | ||||
|     rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue) | ||||
|     light_struct = variable('Application::LightStruct', config[CONF_ID], rhs) | ||||
|     light_struct = variable('Application::MakeLight', config[CONF_ID], rhs) | ||||
|     if CONF_GAMMA_CORRECT in config: | ||||
|         add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT])) | ||||
|     light.setup_mqtt_light_component(light_struct.Pmqtt, config) | ||||
|     setup_mqtt_component(light_struct.Pmqtt, config) | ||||
|     light.setup_light_component(light_struct.Pstate, config) | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import light | ||||
| from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ | ||||
|     CONF_GREEN, CONF_ID, CONF_NAME, CONF_RED, CONF_WHITE | ||||
| from esphomeyaml.helpers import App, get_variable, variable, add | ||||
| from esphomeyaml.helpers import App, add, get_variable, setup_mqtt_component, variable | ||||
|  | ||||
| PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID('rgbw_light'): cv.register_variable_id, | ||||
| @@ -23,7 +23,8 @@ def to_code(config): | ||||
|     blue = get_variable(config[CONF_BLUE]) | ||||
|     white = get_variable(config[CONF_WHITE]) | ||||
|     rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white) | ||||
|     light_struct = variable('Application::LightStruct', config[CONF_ID], rhs) | ||||
|     light_struct = variable('Application::MakeLight', config[CONF_ID], rhs) | ||||
|     if CONF_GAMMA_CORRECT in config: | ||||
|         add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT])) | ||||
|     light.setup_mqtt_light_component(light_struct.Pmqtt, config) | ||||
|     setup_mqtt_component(light_struct.Pmqtt, config) | ||||
|     light.setup_light_component(light_struct.Pstate, config) | ||||
|   | ||||
| @@ -2,20 +2,18 @@ import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGGER, CONF_LOGS, \ | ||||
|     CONF_LOG_TOPIC, CONF_TX_BUFFER_SIZE | ||||
|     CONF_TX_BUFFER_SIZE | ||||
| from esphomeyaml.core import ESPHomeYAMLError | ||||
| from esphomeyaml.helpers import App, Pvariable, RawExpression, add, exp_empty_optional | ||||
| from esphomeyaml.helpers import App, Pvariable, RawExpression, add | ||||
|  | ||||
| LOG_LEVELS = ['NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE'] | ||||
|  | ||||
|  | ||||
| # pylint: disable=invalid-name | ||||
| is_log_level = vol.All(vol.Upper, vol.Any(*LOG_LEVELS)) | ||||
|  | ||||
| CONFIG_SCHEMA = cv.ID_SCHEMA.extend({ | ||||
| CONFIG_SCHEMA = vol.Schema({ | ||||
|     cv.GenerateID(CONF_LOGGER): cv.register_variable_id, | ||||
|     vol.Optional(CONF_BAUD_RATE): cv.positive_int, | ||||
|     vol.Optional(CONF_LOG_TOPIC): vol.Any(None, '', cv.publish_topic), | ||||
|     vol.Optional(CONF_TX_BUFFER_SIZE): cv.positive_int, | ||||
|     vol.Optional(CONF_LEVEL): is_log_level, | ||||
|     vol.Optional(CONF_LOGS): vol.Schema({ | ||||
| @@ -33,16 +31,7 @@ def exp_log_level(level): | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     baud_rate = config.get(CONF_BAUD_RATE) | ||||
|     if baud_rate is None and CONF_LOG_TOPIC in config: | ||||
|         baud_rate = 115200 | ||||
|     log_topic = None | ||||
|     if CONF_LOG_TOPIC in config: | ||||
|         if not config[CONF_LOG_TOPIC]: | ||||
|             log_topic = exp_empty_optional(u'std::string') | ||||
|         else: | ||||
|             log_topic = config[CONF_LOG_TOPIC] | ||||
|     rhs = App.init_log(baud_rate, log_topic) | ||||
|     rhs = App.init_log(config.get(CONF_BAUD_RATE)) | ||||
|     log = Pvariable(u'LogComponent', config[CONF_ID], rhs) | ||||
|     if CONF_TX_BUFFER_SIZE in config: | ||||
|         add(log.set_tx_buffer_size(config[CONF_TX_BUFFER_SIZE])) | ||||
| @@ -56,7 +45,7 @@ def to_code(config): | ||||
|         add(log.set_log_level(tag, exp_log_level(level))) | ||||
|  | ||||
|  | ||||
| def get_build_flags(config): | ||||
| def required_build_flags(config): | ||||
|     if CONF_LEVEL in config: | ||||
|         return u'-DESPHOMELIB_LOG_LEVEL={}'.format(esphomelib_log_level(config[CONF_LEVEL])) | ||||
|     return u'' | ||||
|     return None | ||||
|   | ||||
| @@ -1,11 +1,14 @@ | ||||
| import re | ||||
|  | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_DISCOVERY, \ | ||||
|     CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_MQTT, CONF_PASSWORD, \ | ||||
|     CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_USERNAME, \ | ||||
|     CONF_WILL_MESSAGE, CONF_CLIENT_ID | ||||
| from esphomeyaml.helpers import App, Pvariable, StructInitializer, add, exp_empty_optional | ||||
| 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 | ||||
| from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, StructInitializer, add, \ | ||||
|     exp_empty_optional, RawExpression | ||||
|  | ||||
| MQTT_WILL_BIRTH_SCHEMA = vol.Any(None, vol.Schema({ | ||||
|     vol.Required(CONF_TOPIC): cv.publish_topic, | ||||
| @@ -19,7 +22,7 @@ def validate_broker(value): | ||||
|     value = cv.string_strict(value) | ||||
|     if value.endswith(u'.local'): | ||||
|         raise vol.Invalid(u"MQTT server addresses ending with '.local' are currently unsupported." | ||||
|                           u" Please specify the static IP instead.") | ||||
|                           u" Please use the static IP instead.") | ||||
|     if u':' in value: | ||||
|         raise vol.Invalid(u"Please specify the port using the port: option") | ||||
|     if not value: | ||||
| @@ -27,7 +30,14 @@ def validate_broker(value): | ||||
|     return value | ||||
|  | ||||
|  | ||||
| CONFIG_SCHEMA = cv.ID_SCHEMA.extend({ | ||||
| def validate_fingerprint(value): | ||||
|     value = cv.string(value) | ||||
|     if re.match(r'^[0-9a-f]{40}$', value) is None: | ||||
|         raise vol.Invalid(u"fingerprint must be valid SHA1 hash") | ||||
|     return value | ||||
|  | ||||
|  | ||||
| CONFIG_SCHEMA = vol.Schema({ | ||||
|     cv.GenerateID(CONF_MQTT): cv.register_variable_id, | ||||
|     vol.Required(CONF_BROKER): validate_broker, | ||||
|     vol.Optional(CONF_PORT, default=1883): cv.port, | ||||
| @@ -40,6 +50,9 @@ CONFIG_SCHEMA = cv.ID_SCHEMA.extend({ | ||||
|     vol.Optional(CONF_BIRTH_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, | ||||
|     vol.Optional(CONF_WILL_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, | ||||
|     vol.Optional(CONF_TOPIC_PREFIX): cv.publish_topic, | ||||
|     vol.Optional(CONF_LOG_TOPIC): cv.publish_topic, | ||||
|     vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266, | ||||
|                                                  cv.ensure_list, [validate_fingerprint]), | ||||
| }) | ||||
|  | ||||
|  | ||||
| @@ -74,3 +87,15 @@ def to_code(config): | ||||
|         add(mqtt.set_topic_prefix(config[CONF_TOPIC_PREFIX])) | ||||
|     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])) | ||||
|     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))) | ||||
|  | ||||
|  | ||||
| def required_build_flags(config): | ||||
|     if CONF_SSL_FINGERPRINTS in config: | ||||
|         return '-DASYNC_TCP_SSL_ENABLED=1' | ||||
|     return None | ||||
|   | ||||
| @@ -4,14 +4,15 @@ import logging | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import core | ||||
| from esphomeyaml.const import CONF_ID, CONF_OTA, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE, \ | ||||
|     ESP_PLATFORM_ESP8266, ESP_PLATFORM_ESP32 | ||||
|     ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 | ||||
| from esphomeyaml.core import ESPHomeYAMLError | ||||
| from esphomeyaml.helpers import App, Pvariable, add | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| CONFIG_SCHEMA = cv.ID_SCHEMA.extend({ | ||||
| CONFIG_SCHEMA = vol.Schema({ | ||||
|     cv.GenerateID(CONF_OTA): cv.register_variable_id, | ||||
|     vol.Optional(CONF_SAFE_MODE, default=True): cv.boolean, | ||||
|     # TODO Num attempts + wait time | ||||
| @@ -33,12 +34,16 @@ def to_code(config): | ||||
| def get_port(config): | ||||
|     if CONF_PORT in config[CONF_OTA]: | ||||
|         return config[CONF_OTA][CONF_PORT] | ||||
|     if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|         return 3232 | ||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|         return 8266 | ||||
|     raise ESPHomeYAMLError(u"Invalid ESP Platform for ESP OTA port.") | ||||
|  | ||||
|  | ||||
| def get_auth(config): | ||||
|     return config[CONF_OTA].get(CONF_PASSWORD, '') | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_OTA' | ||||
|   | ||||
| @@ -23,3 +23,7 @@ def setup_output_platform(obj, config, skip_power_supply=False): | ||||
|         add(obj.set_power_supply(power_supply)) | ||||
|     if CONF_MAX_POWER in config: | ||||
|         add(obj.set_max_power(config[CONF_MAX_POWER])) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_OUTPUT' | ||||
|   | ||||
| @@ -2,23 +2,31 @@ import voluptuous as vol | ||||
|  | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.components import output | ||||
| from esphomeyaml.const import CONF_ID, CONF_PIN, \ | ||||
|     ESP_PLATFORM_ESP8266 | ||||
| from esphomeyaml.const import CONF_ID, CONF_PIN, ESP_PLATFORM_ESP8266 | ||||
| from esphomeyaml.core import ESPHomeYAMLError | ||||
| from esphomeyaml.helpers import App, Pvariable, exp_gpio_output_pin, get_gpio_pin_number | ||||
| from esphomeyaml.helpers import App, Pvariable, exp_gpio_output_pin | ||||
|  | ||||
| ESP_PLATFORMS = [ESP_PLATFORM_ESP8266] | ||||
|  | ||||
|  | ||||
| def valid_pwm_pin(value): | ||||
|     if value >= 16: | ||||
|         raise ESPHomeYAMLError(u"ESP8266: Only pins 0-16 support PWM.") | ||||
|     return value | ||||
|  | ||||
|  | ||||
| PLATFORM_SCHEMA = output.FLOAT_PLATFORM_SCHEMA.extend({ | ||||
|     vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, | ||||
|     vol.Required(CONF_PIN): vol.All(pins.GPIO_OUTPUT_PIN_SCHEMA, | ||||
|                                     pins.schema_validate_number(valid_pwm_pin)), | ||||
| }) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     if get_gpio_pin_number(config[CONF_PIN]) >= 16: | ||||
|         # Too difficult to do in config validation | ||||
|         raise ESPHomeYAMLError(u"ESP8266: Only pins 0-16 support PWM.") | ||||
|     pin = exp_gpio_output_pin(config[CONF_PIN]) | ||||
|     rhs = App.make_esp8266_pwm_output(pin) | ||||
|     gpio = Pvariable('output::ESP8266PWMOutput', config[CONF_ID], rhs) | ||||
|     output.setup_output_platform(gpio, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_ESP8266_PWM_OUTPUT' | ||||
|   | ||||
| @@ -15,3 +15,7 @@ def to_code(config): | ||||
|     rhs = App.make_gpio_output(pin) | ||||
|     gpio = Pvariable('output::GPIOBinaryOutputComponent', config[CONF_ID], rhs) | ||||
|     output.setup_output_platform(gpio, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_GPIO_OUTPUT' | ||||
|   | ||||
| @@ -36,3 +36,7 @@ def to_code(config): | ||||
|     if CONF_CHANNEL in config: | ||||
|         add(ledc.set_channel(config[CONF_CHANNEL])) | ||||
|     output.setup_output_platform(ledc, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_LEDC_OUTPUT' | ||||
|   | ||||
| @@ -23,3 +23,7 @@ def to_code(config): | ||||
|     rhs = pca9685.create_channel(config[CONF_CHANNEL], power_supply) | ||||
|     out = Pvariable('output::PCA9685OutputComponent::Channel', config[CONF_ID], rhs) | ||||
|     output.setup_output_platform(out, config, skip_power_supply=True) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_PCA9685_OUTPUT' | ||||
|   | ||||
| @@ -31,3 +31,7 @@ def to_code(config): | ||||
|             phase_balancer = RawExpression(u'PCA9685_PhaseBalancer_{}'.format( | ||||
|                 conf[CONF_PHASE_BALANCER])) | ||||
|             add(pca9685.set_phase_balancer(phase_balancer)) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_PCA9685_OUTPUT' | ||||
|   | ||||
| @@ -23,3 +23,7 @@ def to_code(config): | ||||
|             add(psu.set_enable_time(conf[CONF_ENABLE_TIME])) | ||||
|         if CONF_KEEP_ON_TIME in conf: | ||||
|             add(psu.set_keep_on_time(conf[CONF_KEEP_ON_TIME])) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_OUTPUT' | ||||
|   | ||||
| @@ -3,8 +3,8 @@ import voluptuous as vol | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_EXPIRE_AFTER, \ | ||||
|     CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, CONF_FILTER_NAN, CONF_FILTER_OUT, CONF_ICON, \ | ||||
|     CONF_ID, CONF_LAMBDA, CONF_MULTIPLY, CONF_NAME, CONF_OFFSET, CONF_SEND_EVERY, \ | ||||
|     CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE | ||||
|     CONF_LAMBDA, CONF_MQTT_ID, CONF_MULTIPLY, CONF_NAME, CONF_OFFSET, CONF_SEND_EVERY, \ | ||||
|     CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE, CONF_ID | ||||
| from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add, \ | ||||
|     setup_mqtt_component | ||||
|  | ||||
| @@ -13,7 +13,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | ||||
| }) | ||||
|  | ||||
| FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.Any( | ||||
|     # TODO Fix weird voluptuous error messages | ||||
|     vol.Schema({vol.Required(CONF_OFFSET): vol.Coerce(float)}), | ||||
|     vol.Schema({vol.Required(CONF_MULTIPLY): vol.Coerce(float)}), | ||||
|     vol.Schema({vol.Required(CONF_FILTER_OUT): vol.Coerce(float)}), | ||||
| @@ -43,7 +42,7 @@ MQTT_SENSOR_SCHEMA = vol.Schema({ | ||||
| }) | ||||
|  | ||||
| MQTT_SENSOR_ID_SCHEMA = MQTT_SENSOR_SCHEMA.extend({ | ||||
|     cv.GenerateID('mqtt_sensor'): cv.register_variable_id, | ||||
|     cv.GenerateID('mqtt_sensor', CONF_MQTT_ID): cv.register_variable_id, | ||||
| }) | ||||
|  | ||||
| # pylint: disable=invalid-name | ||||
| @@ -72,30 +71,38 @@ def setup_filter(config): | ||||
|         conf = config[CONF_EXPONENTIAL_MOVING_AVERAGE] | ||||
|         return ExponentialMovingAverageFilter(conf[CONF_ALPHA], conf[CONF_SEND_EVERY]) | ||||
|     if CONF_LAMBDA in config: | ||||
|         s = '[](float x) -> Optional<float> {{ return {}; }}'.format(config[CONF_LAMBDA]) | ||||
|         s = u'[](float x) -> Optional<float> {{ return {}; }}'.format(config[CONF_LAMBDA]) | ||||
|         return LambdaFilter(RawExpression(s)) | ||||
|     raise ValueError("Filter unsupported: {}".format(config)) | ||||
|     raise ValueError(u"Filter unsupported: {}".format(config)) | ||||
|  | ||||
|  | ||||
| def setup_mqtt_sensor_component(obj, config): | ||||
|     if CONF_EXPIRE_AFTER in config: | ||||
|         if config[CONF_EXPIRE_AFTER] is None: | ||||
|             add(obj.disable_expire_after()) | ||||
|         else: | ||||
|             add(obj.set_expire_after(config[CONF_EXPIRE_AFTER])) | ||||
|     setup_mqtt_component(obj, config) | ||||
|  | ||||
|  | ||||
| def setup_sensor(obj, config): | ||||
|     if CONF_UNIT_OF_MEASUREMENT in config: | ||||
|         add(obj.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT])) | ||||
|     if CONF_ICON in config: | ||||
|         add(obj.set_icon(config[CONF_ICON])) | ||||
|     if CONF_ACCURACY_DECIMALS in config: | ||||
|         add(obj.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS])) | ||||
|     if CONF_EXPIRE_AFTER in config: | ||||
|         if config[CONF_EXPIRE_AFTER] is None: | ||||
|             add(obj.disable_expire_after()) | ||||
|         else: | ||||
|             add(obj.set_expire_after(config[CONF_EXPIRE_AFTER])) | ||||
|     if CONF_FILTERS in config: | ||||
|         filters = [setup_filter(x) for x in config[CONF_FILTERS]] | ||||
|         add(obj.set_filters(ArrayInitializer(*filters))) | ||||
|     setup_mqtt_component(obj, config) | ||||
|  | ||||
|  | ||||
| def make_mqtt_sensor_for(exp, config): | ||||
|     rhs = App.make_mqtt_sensor_for(exp, config[CONF_NAME]) | ||||
|     mqtt_sensor = Pvariable('sensor::MQTTSensorComponent', config[CONF_ID], rhs) | ||||
| def register_sensor(var, config): | ||||
|     setup_sensor(var, config) | ||||
|     rhs = App.register_sensor(var) | ||||
|     mqtt_sensor = Pvariable('sensor::MQTTSensorComponent', config[CONF_MQTT_ID], rhs) | ||||
|     setup_mqtt_sensor_component(mqtt_sensor, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_SENSOR' | ||||
|   | ||||
| @@ -25,11 +25,16 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_adc_sensor(config[CONF_PIN], config[CONF_NAME], | ||||
|     rhs = App.make_adc_sensor(config[CONF_NAME], config[CONF_PIN], | ||||
|                               config.get(CONF_UPDATE_INTERVAL)) | ||||
|     make = variable('Application::MakeADCSensor', config[CONF_ID], rhs) | ||||
|     adc = make.Padc | ||||
|     if CONF_ATTENUATION in config: | ||||
|         attenuation = ATTENUATION_MODES[config[CONF_ATTENUATION]] | ||||
|         add(adc.set_attenuation(RawExpression(attenuation))) | ||||
|     sensor.setup_sensor(adc, config) | ||||
|     sensor.setup_mqtt_sensor_component(make.Pmqtt, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_ADC_SENSOR' | ||||
|   | ||||
| @@ -2,8 +2,9 @@ import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import sensor | ||||
| from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_UPDATE_INTERVAL | ||||
| from esphomeyaml.helpers import get_variable, RawExpression | ||||
| from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_UPDATE_INTERVAL, \ | ||||
|     CONF_NAME, CONF_ID | ||||
| from esphomeyaml.helpers import RawExpression, get_variable, Pvariable | ||||
|  | ||||
| DEPENDENCIES = ['ads1115'] | ||||
|  | ||||
| @@ -40,6 +41,7 @@ def validate_gain(value): | ||||
|  | ||||
|  | ||||
| PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID('ads1115_sensor'): cv.register_variable_id, | ||||
|     vol.Required(CONF_MULTIPLEXER): vol.All(vol.Upper, vol.Any(*list(MUX.keys()))), | ||||
|     vol.Required(CONF_GAIN): validate_gain, | ||||
|     vol.Optional(CONF_ADS1115_ID): cv.variable_id, | ||||
| @@ -52,5 +54,10 @@ def to_code(config): | ||||
|  | ||||
|     mux = RawExpression(MUX[config[CONF_MULTIPLEXER]]) | ||||
|     gain = RawExpression(GAIN[config[CONF_GAIN]]) | ||||
|     sensor_ = hub.get_sensor(mux, gain, config.get(CONF_UPDATE_INTERVAL)) | ||||
|     sensor.make_mqtt_sensor_for(sensor_, config) | ||||
|     rhs = hub.get_sensor(config[CONF_NAME], mux, gain, config.get(CONF_UPDATE_INTERVAL)) | ||||
|     sensor_ = Pvariable('sensor::ADS1115Sensor', config[CONF_ID], rhs) | ||||
|     sensor.register_sensor(sensor_, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_ADS1115_SENSOR' | ||||
|   | ||||
| @@ -22,8 +22,14 @@ def to_code(config): | ||||
|     rhs = App.make_bmp085_sensor(config[CONF_TEMPERATURE][CONF_NAME], | ||||
|                                  config[CONF_PRESSURE][CONF_NAME], | ||||
|                                  config.get(CONF_UPDATE_INTERVAL)) | ||||
|     bmp = variable('Application::MakeBMP085Component', config[CONF_ID], rhs) | ||||
|     bmp = variable('Application::MakeBMP085Sensor', config[CONF_ID], rhs) | ||||
|     if CONF_ADDRESS in config: | ||||
|         add(bmp.Pbmp.set_address(HexIntLiteral(config[CONF_ADDRESS]))) | ||||
|     sensor.setup_sensor(bmp.Pbmp.Pget_temperature_sensor(), config[CONF_TEMPERATURE]) | ||||
|     sensor.setup_mqtt_sensor_component(bmp.Pmqtt_temperature, config[CONF_TEMPERATURE]) | ||||
|     sensor.setup_sensor(bmp.Pbmp.Pget_pressure_sensor(), config[CONF_PRESSURE]) | ||||
|     sensor.setup_mqtt_sensor_component(bmp.Pmqtt_pressure, config[CONF_PRESSURE]) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_BMP085_SENSOR' | ||||
|   | ||||
| @@ -3,11 +3,13 @@ import voluptuous as vol | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import sensor | ||||
| from esphomeyaml.components.dallas import DALLAS_COMPONENT_CLASS | ||||
| from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_RESOLUTION, \ | ||||
|     CONF_UPDATE_INTERVAL | ||||
| from esphomeyaml.helpers import HexIntLiteral, get_variable | ||||
| from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_NAME, \ | ||||
|     CONF_RESOLUTION, \ | ||||
|     CONF_UPDATE_INTERVAL, CONF_ID | ||||
| from esphomeyaml.helpers import HexIntLiteral, get_variable, Pvariable | ||||
|  | ||||
| PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID('dallas_sensor'): cv.register_variable_id, | ||||
|     vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int, | ||||
|     vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int, | ||||
|     vol.Optional(CONF_DALLAS_ID): cv.variable_id, | ||||
| @@ -23,9 +25,14 @@ def to_code(config): | ||||
|  | ||||
|     if CONF_ADDRESS in config: | ||||
|         address = HexIntLiteral(config[CONF_ADDRESS]) | ||||
|         sensor_ = hub.Pget_sensor_by_address(address, update_interval, | ||||
|         rhs = hub.Pget_sensor_by_address(config[CONF_NAME], address, update_interval, | ||||
|                                          config.get(CONF_RESOLUTION)) | ||||
|     else: | ||||
|         sensor_ = hub.Pget_sensor_by_index(config[CONF_INDEX], update_interval, | ||||
|                                            config.get(CONF_RESOLUTION)) | ||||
|     sensor.make_mqtt_sensor_for(sensor_, config) | ||||
|         rhs = hub.Pget_sensor_by_index(config[CONF_NAME], config[CONF_INDEX], | ||||
|                                        update_interval, config.get(CONF_RESOLUTION)) | ||||
|     sensor_ = Pvariable('sensor::DallasTemperatureSensor', config[CONF_ID], rhs) | ||||
|     sensor.register_sensor(sensor_, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_DALLAS_SENSOR' | ||||
|   | ||||
| @@ -21,11 +21,18 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_dht_sensor(config[CONF_PIN], config[CONF_TEMPERATURE][CONF_NAME], | ||||
|                               config[CONF_HUMIDITY][CONF_NAME], config.get(CONF_UPDATE_INTERVAL)) | ||||
|     dht = variable('Application::MakeDHTComponent', config[CONF_ID], rhs) | ||||
|     rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME], | ||||
|                               config[CONF_HUMIDITY][CONF_NAME], | ||||
|                               config[CONF_PIN], config.get(CONF_UPDATE_INTERVAL)) | ||||
|     dht = variable('Application::MakeDHTSensor', config[CONF_ID], rhs) | ||||
|     if CONF_MODEL in config: | ||||
|         model = RawExpression('DHT::{}'.format(config[CONF_MODEL])) | ||||
|         add(dht.Pdht.set_dht_model(model)) | ||||
|     sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), config[CONF_TEMPERATURE]) | ||||
|     sensor.setup_mqtt_sensor_component(dht.Pmqtt_temperature, config[CONF_TEMPERATURE]) | ||||
|     sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(), config[CONF_HUMIDITY]) | ||||
|     sensor.setup_mqtt_sensor_component(dht.Pmqtt_humidity, config[CONF_HUMIDITY]) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_DHT_SENSOR' | ||||
|   | ||||
| @@ -21,6 +21,12 @@ def to_code(config): | ||||
|     rhs = App.make_hdc1080_sensor(config[CONF_TEMPERATURE][CONF_NAME], | ||||
|                                   config[CONF_HUMIDITY][CONF_NAME], | ||||
|                                   config.get(CONF_UPDATE_INTERVAL)) | ||||
|     hdc1080 = variable('Application::MakeHDC1080Component', config[CONF_ID], rhs) | ||||
|     hdc1080 = variable('Application::MakeHDC1080Sensor', config[CONF_ID], rhs) | ||||
|     sensor.setup_sensor(hdc1080.Phdc1080.Pget_temperature_sensor(), config[CONF_TEMPERATURE]) | ||||
|     sensor.setup_mqtt_sensor_component(hdc1080.Pmqtt_temperature, config[CONF_TEMPERATURE]) | ||||
|     sensor.setup_sensor(hdc1080.Phdc1080.Pget_humidity_sensor(), config[CONF_HUMIDITY]) | ||||
|     sensor.setup_mqtt_sensor_component(hdc1080.Pmqtt_humidity, config[CONF_HUMIDITY]) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_HDC1080_SENSOR' | ||||
|   | ||||
| @@ -21,6 +21,12 @@ def to_code(config): | ||||
|     rhs = App.make_htu21d_sensor(config[CONF_TEMPERATURE][CONF_NAME], | ||||
|                                  config[CONF_HUMIDITY][CONF_NAME], | ||||
|                                  config.get(CONF_UPDATE_INTERVAL)) | ||||
|     htu21d = variable('Application::MakeHTU21DComponent', config[CONF_ID], rhs) | ||||
|     htu21d = variable('Application::MakeHTU21DSensor', config[CONF_ID], rhs) | ||||
|     sensor.setup_sensor(htu21d.Phtu21d.Pget_temperature_sensor(), config[CONF_TEMPERATURE]) | ||||
|     sensor.setup_mqtt_sensor_component(htu21d.Pmqtt_temperature, config[CONF_TEMPERATURE]) | ||||
|     sensor.setup_sensor(htu21d.Phtu21d.Pget_humidity_sensor(), config[CONF_HUMIDITY]) | ||||
|     sensor.setup_mqtt_sensor_component(htu21d.Pmqtt_humidity, config[CONF_HUMIDITY]) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_HTU21D_SENSOR' | ||||
|   | ||||
| @@ -41,9 +41,9 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_pulse_counter_sensor(config[CONF_PIN], config[CONF_NAME], | ||||
|     rhs = App.make_pulse_counter_sensor(config[CONF_NAME], config[CONF_PIN], | ||||
|                                         config.get(CONF_UPDATE_INTERVAL)) | ||||
|     make = variable('Application::MakePulseCounter', config[CONF_ID], rhs) | ||||
|     make = variable('Application::MakePulseCounterSensor', config[CONF_ID], rhs) | ||||
|     pcnt = make.Ppcnt | ||||
|     if CONF_PULL_MODE in config: | ||||
|         pull_mode = GPIO_PULL_MODES[config[CONF_PULL_MODE]] | ||||
| @@ -55,4 +55,9 @@ def to_code(config): | ||||
|         add(pcnt.set_edge_mode(RawExpression(rising_edge), RawExpression(falling_edge))) | ||||
|     if CONF_INTERNAL_FILTER in config: | ||||
|         add(pcnt.set_filter(config[CONF_INTERNAL_FILTER])) | ||||
|     sensor.setup_sensor(pcnt, config) | ||||
|     sensor.setup_mqtt_sensor_component(make.Pmqtt, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_PULSE_COUNTER_SENSOR' | ||||
|   | ||||
| @@ -21,7 +21,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ | ||||
| def to_code(config): | ||||
|     trigger = exp_gpio_output_pin(config[CONF_TRIGGER_PIN]) | ||||
|     echo = exp_gpio_input_pin(config[CONF_ECHO_PIN]) | ||||
|     rhs = App.make_ultrasonic_sensor(trigger, echo, config[CONF_NAME], | ||||
|     rhs = App.make_ultrasonic_sensor(config[CONF_NAME], trigger, echo, | ||||
|                                      config.get(CONF_UPDATE_INTERVAL)) | ||||
|     make = variable('Application::MakeUltrasonicSensor', config[CONF_ID], rhs) | ||||
|     ultrasonic = make.Pultrasonic | ||||
| @@ -29,4 +29,9 @@ def to_code(config): | ||||
|         add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT_TIME])) | ||||
|     elif CONF_TIMEOUT_METER in config: | ||||
|         add(ultrasonic.set_timeout_m(config[CONF_TIMEOUT_METER])) | ||||
|     sensor.setup_sensor(ultrasonic, config) | ||||
|     sensor.setup_mqtt_sensor_component(make.Pmqtt, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_ULTRASONIC_SENSOR' | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_ICON, CONF_ID, CONF_NAME | ||||
| from esphomeyaml.const import CONF_ICON, CONF_ID, CONF_NAME, CONF_MQTT_ID | ||||
| from esphomeyaml.helpers import App, Pvariable, add, setup_mqtt_component | ||||
|  | ||||
| PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | ||||
| @@ -12,14 +12,26 @@ MQTT_SWITCH_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ | ||||
|     vol.Optional(CONF_ICON): cv.icon, | ||||
| }) | ||||
|  | ||||
| MQTT_SWITCH_ID_SCHEMA = MQTT_SWITCH_SCHEMA.extend({ | ||||
|     cv.GenerateID('mqtt_switch', CONF_MQTT_ID): cv.register_variable_id, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def setup_mqtt_switch(obj, config): | ||||
|     if CONF_ICON in config: | ||||
|         add(obj.set_icon(config[CONF_ICON])) | ||||
|     setup_mqtt_component(obj, config) | ||||
|  | ||||
|  | ||||
| def make_mqtt_switch_for(exp, config): | ||||
|     rhs = App.make_mqtt_switch_for(exp, config[CONF_NAME]) | ||||
|     mqtt_switch = Pvariable('switch_::MQTTSwitchComponent', config[CONF_ID], rhs) | ||||
| def setup_switch(obj, config): | ||||
|     if CONF_ICON in config: | ||||
|         add(obj.set_icon(config[CONF_ICON])) | ||||
|  | ||||
|  | ||||
| def register_switch(var, config): | ||||
|     setup_switch(var, config) | ||||
|     rhs = App.register_switch(var) | ||||
|     mqtt_switch = Pvariable('switch_::MQTTSwitchComponent', config[CONF_MQTT_ID], rhs) | ||||
|     setup_mqtt_switch(mqtt_switch, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_SWITCH' | ||||
|   | ||||
| @@ -13,6 +13,11 @@ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_gpio_switch(exp_gpio_output_pin(config[CONF_PIN]), config[CONF_NAME]) | ||||
|     gpio = variable('Application::GPIOSwitchStruct', config[CONF_ID], rhs) | ||||
|     rhs = App.make_gpio_switch(config[CONF_NAME], exp_gpio_output_pin(config[CONF_PIN])) | ||||
|     gpio = variable('Application::MakeGPIOSwitch', config[CONF_ID], rhs) | ||||
|     switch.setup_switch(gpio.Pswitch_, config) | ||||
|     switch.setup_mqtt_switch(gpio.Pmqtt, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_GPIO_SWITCH' | ||||
|   | ||||
| @@ -5,12 +5,12 @@ from esphomeyaml.components import switch | ||||
| from esphomeyaml.components.ir_transmitter import IR_TRANSMITTER_COMPONENT_CLASS | ||||
| from esphomeyaml.const import CONF_ADDRESS, CONF_COMMAND, CONF_DATA, CONF_IR_TRANSMITTER_ID, \ | ||||
|     CONF_LG, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_REPEAT, CONF_SONY, CONF_TIMES, \ | ||||
|     CONF_WAIT_TIME_US, CONF_RAW, CONF_CARRIER_FREQUENCY | ||||
|     CONF_WAIT_TIME_US, CONF_RAW, CONF_CARRIER_FREQUENCY, CONF_NAME, CONF_ID | ||||
| from esphomeyaml.core import ESPHomeYAMLError | ||||
| from esphomeyaml.helpers import HexIntLiteral, MockObj, get_variable, ArrayInitializer | ||||
| from esphomeyaml.helpers import HexIntLiteral, MockObj, get_variable, ArrayInitializer, Pvariable | ||||
|  | ||||
| PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID('ir_transmitter'): cv.register_variable_id, | ||||
|     cv.GenerateID('ir_transmitter_switch'): cv.register_variable_id, | ||||
|     vol.Exclusive(CONF_NEC, 'code'): vol.Schema({ | ||||
|         vol.Required(CONF_ADDRESS): cv.hex_uint16_t, | ||||
|         vol.Required(CONF_COMMAND): cv.hex_uint16_t, | ||||
| @@ -36,7 +36,7 @@ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ | ||||
|         vol.Required(CONF_WAIT_TIME_US): cv.uint32_t, | ||||
|     })), | ||||
|     vol.Optional(CONF_IR_TRANSMITTER_ID): cv.variable_id, | ||||
| }).extend(switch.MQTT_SWITCH_SCHEMA.schema) | ||||
| }).extend(switch.MQTT_SWITCH_ID_SCHEMA.schema) | ||||
|  | ||||
|  | ||||
| # pylint: disable=invalid-name | ||||
| @@ -86,4 +86,11 @@ def exp_send_data(config): | ||||
| def to_code(config): | ||||
|     ir = get_variable(config.get(CONF_IR_TRANSMITTER_ID), IR_TRANSMITTER_COMPONENT_CLASS) | ||||
|     send_data = exp_send_data(config) | ||||
|     switch.make_mqtt_switch_for(ir.create_transmitter(send_data), config) | ||||
|     rhs = ir.create_transmitter(config[CONF_NAME], send_data) | ||||
|     switch_ = Pvariable(IR_TRANSMITTER_COMPONENT_CLASS + '::DataTransmitter', config[CONF_ID], | ||||
|                         rhs) | ||||
|     switch.register_switch(switch_, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_IR_TRANSMITTER' | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import switch | ||||
| from esphomeyaml.const import CONF_ID, CONF_NAME | ||||
| from esphomeyaml.helpers import App, Pvariable | ||||
| from esphomeyaml.helpers import App, variable | ||||
|  | ||||
| PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID('restart_switch'): cv.register_variable_id, | ||||
| @@ -10,5 +10,10 @@ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_restart_switch(config[CONF_NAME]) | ||||
|     mqtt = Pvariable('switch_::MQTTSwitchComponent', config[CONF_ID], rhs) | ||||
|     switch.setup_mqtt_switch(mqtt, config) | ||||
|     restart = variable('Application::MakeRestartSwitch', config[CONF_ID], rhs) | ||||
|     switch.setup_switch(restart.Prestart, config) | ||||
|     switch.setup_mqtt_switch(restart.Pmqtt, config) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_RESTART_SWITCH' | ||||
|   | ||||
							
								
								
									
										29
									
								
								esphomeyaml/components/web_server.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								esphomeyaml/components/web_server.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| import logging | ||||
|  | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_PORT, CONF_JS_URL, CONF_CSS_URL, CONF_ID | ||||
| from esphomeyaml.helpers import App, add, Pvariable | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| CONFIG_SCHEMA = vol.Schema({ | ||||
|     cv.GenerateID('web_server'): cv.register_variable_id, | ||||
|     vol.Optional(CONF_PORT): cv.port, | ||||
|     vol.Optional(CONF_CSS_URL): vol.Url, | ||||
|     vol.Optional(CONF_JS_URL): vol.Url, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.init_web_server(config.get(CONF_PORT)) | ||||
|     web_server = Pvariable('WebServer', config[CONF_ID], rhs) | ||||
|     if CONF_CSS_URL in config: | ||||
|         add(web_server.set_css_url(config[CONF_CSS_URL])) | ||||
|     if CONF_JS_URL in config: | ||||
|         add(web_server.set_js_url(config[CONF_JS_URL])) | ||||
|  | ||||
|  | ||||
| def build_flags(config): | ||||
|     return '-DUSE_WEB_SERVER' | ||||
| @@ -1,25 +1,47 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_DNS1, CONF_DNS2, CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, \ | ||||
|     CONF_MANUAL_IP, CONF_PASSWORD, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, CONF_WIFI | ||||
| from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_GATEWAY, \ | ||||
|     CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET | ||||
| from esphomeyaml.helpers import App, MockObj, Pvariable, StructInitializer, add | ||||
|  | ||||
| CONFIG_SCHEMA = cv.ID_SCHEMA.extend({ | ||||
|     cv.GenerateID(CONF_WIFI): cv.register_variable_id, | ||||
|     vol.Required(CONF_SSID): cv.ssid, | ||||
|     vol.Optional(CONF_PASSWORD): cv.string, | ||||
|     vol.Optional(CONF_MANUAL_IP): vol.Schema({ | ||||
|  | ||||
| def validate_password(value): | ||||
|     value = cv.string(value) | ||||
|     if not value: | ||||
|         return value | ||||
|     if len(value) < 8: | ||||
|         raise vol.Invalid(u"WPA password must be at least 8 characters long") | ||||
|     if len(value) > 63: | ||||
|         raise vol.Invalid(u"WPA password must be at most 63 characters long") | ||||
|     return value | ||||
|  | ||||
|  | ||||
| AP_MANUAL_IP_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_STATIC_IP): cv.ipv4, | ||||
|     vol.Required(CONF_GATEWAY): cv.ipv4, | ||||
|     vol.Required(CONF_SUBNET): cv.ipv4, | ||||
| }) | ||||
|  | ||||
| STA_MANUAL_IP_SCHEMA = AP_MANUAL_IP_SCHEMA.extend({ | ||||
|     vol.Inclusive(CONF_DNS1, 'dns'): cv.ipv4, | ||||
|     vol.Inclusive(CONF_DNS2, 'dns'): cv.ipv4, | ||||
| }) | ||||
|  | ||||
| CONFIG_SCHEMA = vol.Schema({ | ||||
|     cv.GenerateID('wifi'): cv.register_variable_id, | ||||
|     vol.Optional(CONF_SSID): cv.ssid, | ||||
|     vol.Optional(CONF_PASSWORD): validate_password, | ||||
|     vol.Optional(CONF_MANUAL_IP): STA_MANUAL_IP_SCHEMA, | ||||
|     vol.Optional(CONF_AP): vol.Schema({ | ||||
|         vol.Required(CONF_SSID): cv.ssid, | ||||
|         vol.Optional(CONF_PASSWORD): validate_password, | ||||
|         vol.Optional(CONF_CHANNEL): vol.All(cv.positive_int, vol.Range(min=1, max=14)), | ||||
|         vol.Optional(CONF_MANUAL_IP): AP_MANUAL_IP_SCHEMA, | ||||
|     }), | ||||
|     vol.Optional(CONF_HOSTNAME): cv.hostname, | ||||
| }) | ||||
|  | ||||
|  | ||||
| # pylint: disable=invalid-name | ||||
| IPAddress = MockObj('IPAddress') | ||||
|  | ||||
| @@ -30,19 +52,38 @@ def safe_ip(ip): | ||||
|     return IPAddress(*ip.args) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.init_wifi(config[CONF_SSID], config.get(CONF_PASSWORD)) | ||||
|     wifi = Pvariable('WiFiComponent', config[CONF_ID], rhs) | ||||
|     if CONF_MANUAL_IP in config: | ||||
|         manual_ip = config[CONF_MANUAL_IP] | ||||
|         exp = StructInitializer( | ||||
| def manual_ip(config): | ||||
|     return StructInitializer( | ||||
|         'ManualIP', | ||||
|             ('static_ip', safe_ip(manual_ip[CONF_STATIC_IP])), | ||||
|             ('gateway', safe_ip(manual_ip[CONF_GATEWAY])), | ||||
|             ('subnet', safe_ip(manual_ip[CONF_SUBNET])), | ||||
|             ('dns1', safe_ip(manual_ip.get(CONF_DNS1))), | ||||
|             ('dns2', safe_ip(manual_ip.get(CONF_DNS2))), | ||||
|         ('static_ip', safe_ip(config[CONF_STATIC_IP])), | ||||
|         ('gateway', safe_ip(config[CONF_GATEWAY])), | ||||
|         ('subnet', safe_ip(config[CONF_SUBNET])), | ||||
|         ('dns1', safe_ip(config.get(CONF_DNS1))), | ||||
|         ('dns2', safe_ip(config.get(CONF_DNS2))), | ||||
|     ) | ||||
|         add(wifi.set_manual_ip(exp)) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     sta = CONF_SSID in config | ||||
|     ap = CONF_AP in config | ||||
|     if sta: | ||||
|         rhs = App.init_wifi(config[CONF_SSID], config.get(CONF_PASSWORD)) | ||||
|     else: | ||||
|         rhs = App.init_wifi() | ||||
|     wifi = Pvariable('WiFiComponent', config[CONF_ID], rhs) | ||||
|  | ||||
|     if sta and CONF_MANUAL_IP in config: | ||||
|         add(wifi.set_sta_manual_ip(manual_ip(config[CONF_MANUAL_IP]))) | ||||
|  | ||||
|     if ap: | ||||
|         conf = config[CONF_AP] | ||||
|         password = config.get(CONF_PASSWORD) | ||||
|         if password is None and CONF_CHANNEL in conf: | ||||
|             password = u"" | ||||
|         add(wifi.set_ap(conf[CONF_SSID], password, conf.get(CONF_CHANNEL))) | ||||
|  | ||||
|         if CONF_MANUAL_IP in conf: | ||||
|             add(wifi.set_ap_manual_ip(manual_ip(conf[CONF_MANUAL_IP]))) | ||||
|  | ||||
|     if CONF_HOSTNAME in config: | ||||
|         add(wifi.set_hostname(config[CONF_HOSTNAME])) | ||||
|   | ||||
| @@ -8,13 +8,12 @@ import voluptuous as vol | ||||
| from voluptuous.humanize import humanize_error | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import helpers, yaml_util | ||||
| from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_MQTT, \ | ||||
|     CONF_NAME, \ | ||||
|     CONF_PLATFORM, CONF_SIMPLIFY, CONF_WIFI, ESP_PLATFORMS, ESP_PLATFORM_ESP32, \ | ||||
|     ESP_PLATFORM_ESP8266 | ||||
| from esphomeyaml import core, yaml_util | ||||
| from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_NAME, \ | ||||
|     CONF_PLATFORM, CONF_SIMPLIFY, CONF_USE_BUILD_FLAGS, CONF_WIFI, ESP_PLATFORMS, \ | ||||
|     ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 | ||||
| from esphomeyaml.core import ESPHomeYAMLError | ||||
| from esphomeyaml.helpers import App, add, add_task, color | ||||
| from esphomeyaml.helpers import App, add, color | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| @@ -22,15 +21,15 @@ DEFAULT_LIBRARY_URI = u'esphomelib@1.2.1' | ||||
|  | ||||
| CORE_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_NAME): cv.valid_name, | ||||
|     vol.Required(CONF_PLATFORM): vol.All( | ||||
|         vol.Upper, vol.Any(ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266)), | ||||
|     vol.Required(CONF_PLATFORM): cv.string, | ||||
|     vol.Required(CONF_BOARD): cv.string, | ||||
|     vol.Optional(CONF_LIBRARY_URI, default=DEFAULT_LIBRARY_URI): cv.string, | ||||
|     vol.Optional(CONF_SIMPLIFY, default=True): cv.boolean, | ||||
|     vol.Optional(CONF_USE_BUILD_FLAGS, default=False): cv.boolean, | ||||
| }) | ||||
|  | ||||
| REQUIRED_COMPONENTS = [ | ||||
|     CONF_ESPHOMEYAML, CONF_WIFI, CONF_MQTT | ||||
|     CONF_ESPHOMEYAML, CONF_WIFI | ||||
| ] | ||||
|  | ||||
| _COMPONENT_CACHE = {} | ||||
| @@ -66,8 +65,17 @@ def is_platform_component(component): | ||||
|     return hasattr(component, 'PLATFORM_SCHEMA') | ||||
|  | ||||
|  | ||||
| def validate_schema(config, schema): | ||||
|     return schema(config) | ||||
| def iter_components(config): | ||||
|     for domain, conf in config.iteritems(): | ||||
|         if domain == CONF_ESPHOMEYAML: | ||||
|             continue | ||||
|         component = get_component(domain) | ||||
|         yield domain, component, conf | ||||
|         if is_platform_component(component): | ||||
|             for p_config in conf: | ||||
|                 p_name = u"{}.{}".format(domain, p_config[CONF_PLATFORM]) | ||||
|                 platform = get_component(p_name) | ||||
|                 yield p_name, platform, p_config | ||||
|  | ||||
|  | ||||
| class Config(OrderedDict): | ||||
| @@ -96,7 +104,7 @@ def validate_config(config): | ||||
|         result.add_error(_format_config_error(ex, domain, config), domain, config) | ||||
|  | ||||
|     try: | ||||
|         result[CONF_ESPHOMEYAML] = validate_schema(config[CONF_ESPHOMEYAML], CORE_SCHEMA) | ||||
|         result[CONF_ESPHOMEYAML] = CORE_SCHEMA(config[CONF_ESPHOMEYAML]) | ||||
|     except vol.Invalid as ex: | ||||
|         _comp_error(ex, CONF_ESPHOMEYAML, config) | ||||
|  | ||||
| @@ -111,8 +119,8 @@ def validate_config(config): | ||||
|             continue | ||||
|  | ||||
|         esp_platforms = getattr(component, 'ESP_PLATFORMS', ESP_PLATFORMS) | ||||
|         if cv.ESP_PLATFORM not in esp_platforms: | ||||
|             result.add_error(u"Component {} doesn't support {}.".format(domain, cv.ESP_PLATFORM)) | ||||
|         if core.ESP_PLATFORM not in esp_platforms: | ||||
|             result.add_error(u"Component {} doesn't support {}.".format(domain, core.ESP_PLATFORM)) | ||||
|             continue | ||||
|  | ||||
|         success = True | ||||
| @@ -129,7 +137,7 @@ def validate_config(config): | ||||
|                 validated = component.CONFIG_SCHEMA(conf) | ||||
|                 result[domain] = validated | ||||
|             except vol.Invalid as ex: | ||||
|                 _comp_error(ex, domain, config) | ||||
|                 _comp_error(ex, domain, conf) | ||||
|                 continue | ||||
|  | ||||
|         if not hasattr(component, 'PLATFORM_SCHEMA'): | ||||
| @@ -138,7 +146,7 @@ def validate_config(config): | ||||
|         platforms = [] | ||||
|         for p_config in conf: | ||||
|             if not isinstance(p_config, dict): | ||||
|                 result.add_error(u"Platform schemas mus have 'platform:' key") | ||||
|                 result.add_error(u"Platform schemas must have 'platform:' key") | ||||
|                 continue | ||||
|             p_name = p_config.get(u'platform') | ||||
|             if p_name is None: | ||||
| @@ -149,6 +157,16 @@ def validate_config(config): | ||||
|                 result.add_error(u"Platform not found: {}.{}") | ||||
|                 continue | ||||
|  | ||||
|             success = True | ||||
|             dependencies = getattr(platform, 'DEPENDENCIES', []) | ||||
|             for dependency in dependencies: | ||||
|                 if dependency not in _ALL_COMPONENTS: | ||||
|                     result.add_error(u"Platform {}.{} requires {}".format(domain, p_name, | ||||
|                                                                           dependency)) | ||||
|                     success = False | ||||
|             if not success: | ||||
|                 continue | ||||
|  | ||||
|             if hasattr(platform, u'PLATFORM_SCHEMA'): | ||||
|                 try: | ||||
|                     p_validated = platform.PLATFORM_SCHEMA(p_config) | ||||
| @@ -160,7 +178,7 @@ def validate_config(config): | ||||
|     return result | ||||
|  | ||||
|  | ||||
| REQUIRED = ['esphomeyaml', 'wifi', 'mqtt'] | ||||
| REQUIRED = ['esphomeyaml', 'wifi'] | ||||
|  | ||||
|  | ||||
| def _format_config_error(ex, domain, config): | ||||
| @@ -186,13 +204,18 @@ def load_config(path): | ||||
|     except OSError: | ||||
|         raise ESPHomeYAMLError(u"Could not read configuration file at {}".format(path)) | ||||
|  | ||||
|     esp_platform = unicode(config.get(CONF_ESPHOMEYAML, {}).get(CONF_PLATFORM, u"")) | ||||
|     if CONF_ESPHOMEYAML not in config: | ||||
|         raise ESPHomeYAMLError(u"No esphomeyaml section in config") | ||||
|     core_conf = config[CONF_ESPHOMEYAML] | ||||
|     esp_platform = unicode(core_conf.get(CONF_PLATFORM, u"")) | ||||
|     esp_platform = esp_platform.upper() | ||||
|     if esp_platform not in (ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266): | ||||
|         raise ESPHomeYAMLError(u"Invalid ESP Platform {}".format(esp_platform)) | ||||
|     cv.ESP_PLATFORM = esp_platform | ||||
|     cv.BOARD = unicode(config.get(CONF_ESPHOMEYAML, {}).get(CONF_BOARD, u"")) | ||||
|     helpers.SIMPLIFY = cv.boolean(config.get(CONF_SIMPLIFY, True)) | ||||
|     if '8266' in esp_platform: | ||||
|         esp_platform = ESP_PLATFORM_ESP8266 | ||||
|     if '32' in esp_platform: | ||||
|         esp_platform = ESP_PLATFORM_ESP32 | ||||
|     core.ESP_PLATFORM = esp_platform | ||||
|     core.BOARD = unicode(core_conf.get(CONF_BOARD, u"")) | ||||
|     core.SIMPLIFY = cv.boolean(core_conf.get(CONF_SIMPLIFY, True)) | ||||
|  | ||||
|     try: | ||||
|         result = validate_config(config) | ||||
| @@ -203,28 +226,6 @@ def load_config(path): | ||||
|     return result | ||||
|  | ||||
|  | ||||
| def add_platform_task(domain, config): | ||||
|     platform_ = config[CONF_PLATFORM] | ||||
|     platform = get_platform(domain, platform_) | ||||
|     if not hasattr(platform, 'to_code'): | ||||
|         raise ESPHomeYAMLError(u"Platform '{}.{}' doesn't have to_code.".format(domain, platform_)) | ||||
|     add_task(platform.to_code, config) | ||||
|  | ||||
|  | ||||
| def add_component_task(domain, config): | ||||
|     if domain == CONF_ESPHOMEYAML: | ||||
|         add_task(core_to_code, config) | ||||
|         return | ||||
|     component = get_component(domain) | ||||
|     if is_platform_component(component): | ||||
|         for conf in config: | ||||
|             add_platform_task(domain, conf) | ||||
|     else: | ||||
|         if not hasattr(component, 'to_code'): | ||||
|             raise ESPHomeYAMLError(u"Component '{}' doesn't have to_code.".format(domain)) | ||||
|         add_task(component.to_code, config) | ||||
|  | ||||
|  | ||||
| def line_info(obj, **kwargs): | ||||
|     """Display line config source.""" | ||||
|     if hasattr(obj, '__config_file__'): | ||||
|   | ||||
| @@ -7,6 +7,7 @@ from datetime import timedelta | ||||
|  | ||||
| import voluptuous as vol | ||||
|  | ||||
| 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, \ | ||||
| @@ -24,9 +25,6 @@ zero_to_one_float = vol.All(vol.Coerce(float), vol.Range(min=0, max=1)) | ||||
| positive_int = vol.All(vol.Coerce(int), vol.Range(min=0)) | ||||
| positive_not_null_int = vol.All(vol.Coerce(int), vol.Range(min=0, min_included=False)) | ||||
|  | ||||
| ESP_PLATFORM = '' | ||||
| BOARD = '' | ||||
|  | ||||
| ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_' | ||||
|  | ||||
| RESERVED_IDS = [ | ||||
| @@ -150,7 +148,7 @@ def only_on(platforms): | ||||
|         platforms = [platforms] | ||||
|  | ||||
|     def validator_(obj): | ||||
|         if 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 | ||||
|  | ||||
| @@ -274,8 +272,8 @@ def ssid(value): | ||||
|         raise vol.Invalid("SSID must be a string. Did you wrap it in quotes?") | ||||
|     if not value: | ||||
|         raise vol.Invalid("SSID can't be empty.") | ||||
|     if len(value) > 32: | ||||
|         raise vol.Invalid("SSID can't be longer than 32 characters") | ||||
|     if len(value) > 31: | ||||
|         raise vol.Invalid("SSID can't be longer than 31 characters") | ||||
|     return value | ||||
|  | ||||
|  | ||||
| @@ -300,6 +298,8 @@ 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 '#'") | ||||
|     return value | ||||
|  | ||||
|  | ||||
| @@ -334,23 +334,19 @@ def register_variable_id(value): | ||||
|  | ||||
|  | ||||
| class GenerateID(vol.Optional): | ||||
|     def __init__(self, basename): | ||||
|     def __init__(self, basename, key=CONF_ID): | ||||
|         self._basename = basename | ||||
|         super(GenerateID, self).__init__(CONF_ID, default=self.default_variable_id) | ||||
|         super(GenerateID, self).__init__(key, default=self.default_variable_id) | ||||
|  | ||||
|     def default_variable_id(self): | ||||
|         return ensure_unique_string(self._basename, REGISTERED_IDS) | ||||
|  | ||||
|  | ||||
| ID_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_ID): invalid, | ||||
| }) | ||||
|  | ||||
| REQUIRED_ID_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_ID): register_variable_id, | ||||
| }) | ||||
|  | ||||
| PLATFORM_SCHEMA = ID_SCHEMA.extend({ | ||||
| PLATFORM_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_PLATFORM): valid, | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| MAJOR_VERSION = 1 | ||||
| MINOR_VERSION = 2 | ||||
| PATCH_VERSION = '2' | ||||
| PATCH_VERSION = '2-dev' | ||||
| __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) | ||||
| __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) | ||||
|  | ||||
| @@ -17,6 +17,7 @@ CONF_NAME = 'name' | ||||
| CONF_PLATFORM = 'platform' | ||||
| CONF_BOARD = 'board' | ||||
| CONF_SIMPLIFY = 'simplify' | ||||
| CONF_USE_BUILD_FLAGS = 'use_build_flags' | ||||
| CONF_LIBRARY_URI = 'library_uri' | ||||
| CONF_LOGGER = 'logger' | ||||
| CONF_WIFI = 'wifi' | ||||
| @@ -32,6 +33,7 @@ CONF_BROKER = 'broker' | ||||
| CONF_USERNAME = 'username' | ||||
| CONF_POWER_SUPPLY = 'power_supply' | ||||
| CONF_ID = 'id' | ||||
| CONF_MQTT_ID = 'mqtt_id' | ||||
| CONF_PIN = 'pin' | ||||
| CONF_NUMBER = 'number' | ||||
| CONF_INVERTED = 'inverted' | ||||
| @@ -151,6 +153,14 @@ CONF_RATE = 'rate' | ||||
| CONF_ADS1115_ID = 'ads1115_id' | ||||
| CONF_MULTIPLEXER = 'multiplexer' | ||||
| CONF_GAIN = 'gain' | ||||
| CONF_SLEEP_DURATION = 'sleep_duration' | ||||
| CONF_WAKEUP_PIN = 'wakeup_pin' | ||||
| CONF_RUN_CYCLES = 'run_cycles' | ||||
| CONF_RUN_DURATION = 'run_duration' | ||||
| CONF_AP = 'ap' | ||||
| CONF_CSS_URL = 'css_url' | ||||
| CONF_JS_URL = 'js_url' | ||||
| CONF_FINGERPRINTS = 'fingerprints' | ||||
|  | ||||
| ESP32_BOARDS = [ | ||||
|     'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', | ||||
|   | ||||
| @@ -16,3 +16,9 @@ class IPAddress(object): | ||||
|  | ||||
|     def __str__(self): | ||||
|         return '.'.join(str(x) for x in self.args) | ||||
|  | ||||
|  | ||||
| CONFIG_PATH = None | ||||
| SIMPLIFY = True | ||||
| ESP_PLATFORM = '' | ||||
| BOARD = '' | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import logging | ||||
| import re | ||||
| from collections import OrderedDict, deque | ||||
|  | ||||
| from esphomeyaml import core | ||||
| from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, \ | ||||
|     CONF_INVERTED, \ | ||||
|     CONF_MODE, CONF_NUMBER, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_RETAIN, \ | ||||
| @@ -12,8 +13,6 @@ from esphomeyaml.core import ESPHomeYAMLError, HexInt | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| SIMPLIFY = False | ||||
|  | ||||
|  | ||||
| def ensure_unique_string(preferred_string, current_strings): | ||||
|     test_string = preferred_string | ||||
| @@ -45,11 +44,19 @@ def indent(text, padding=u'  '): | ||||
|  | ||||
| class Expression(object): | ||||
|     def __init__(self): | ||||
|         pass | ||||
|         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() | ||||
|  | ||||
|  | ||||
| class RawExpression(Expression): | ||||
|     def __init__(self, text): | ||||
| @@ -60,15 +67,22 @@ class RawExpression(Expression): | ||||
|         return self.text | ||||
|  | ||||
|  | ||||
| # pylint: disable=redefined-builtin | ||||
| class AssignmentExpression(Expression): | ||||
|     def __init__(self, lhs, rhs, obj): | ||||
|     def __init__(self, type, modifier, name, rhs, obj): | ||||
|         super(AssignmentExpression, self).__init__() | ||||
|         self.obj = obj | ||||
|         self.lhs = safe_exp(lhs) | ||||
|         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): | ||||
|         return u"{} = {}".format(self.lhs, self.rhs) | ||||
|         type_ = self.type | ||||
|         if core.SIMPLIFY: | ||||
|             type_ = u'auto' | ||||
|         return u"{} {}{} = {}".format(type_, self.modifier, self.name, self.rhs) | ||||
|  | ||||
|  | ||||
| class ExpressionList(Expression): | ||||
| @@ -78,7 +92,11 @@ class ExpressionList(Expression): | ||||
|         args = list(args) | ||||
|         while args and args[-1] is None: | ||||
|             args.pop() | ||||
|         self.args = [safe_exp(x) for x in args] | ||||
|         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) | ||||
| @@ -90,6 +108,7 @@ class CallExpression(Expression): | ||||
|         super(CallExpression, self).__init__() | ||||
|         self.base = base | ||||
|         self.args = ExpressionList(*args) | ||||
|         self.requires.append(self.args) | ||||
|  | ||||
|     def __str__(self): | ||||
|         return u'{}({})'.format(self.base, self.args) | ||||
| @@ -103,8 +122,11 @@ class StructInitializer(Expression): | ||||
|             args = OrderedDict(args) | ||||
|         self.args = OrderedDict() | ||||
|         for key, value in args.iteritems(): | ||||
|             if value is not None: | ||||
|                 self.args[key] = safe_exp(value) | ||||
|             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) | ||||
| @@ -115,17 +137,27 @@ class StructInitializer(Expression): | ||||
|  | ||||
|  | ||||
| class ArrayInitializer(Expression): | ||||
|     def __init__(self, *args): | ||||
|     def __init__(self, *args, **kwargs): | ||||
|         super(ArrayInitializer, self).__init__() | ||||
|         self.args = [safe_exp(x) for x in args if x is not None] | ||||
|         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 | ||||
|  | ||||
|  | ||||
| @@ -227,20 +259,22 @@ def statement(expression): | ||||
|  | ||||
| # pylint: disable=redefined-builtin, invalid-name | ||||
| def variable(type, id, rhs): | ||||
|     lhs = RawExpression(u'{} {}'.format(type if not SIMPLIFY else u'auto', id)) | ||||
|     rhs = safe_exp(rhs) | ||||
|     obj = MockObj(id, u'.') | ||||
|     add(AssignmentExpression(lhs, rhs, obj)) | ||||
|     assignment = AssignmentExpression(type, '', id, rhs, obj) | ||||
|     add(assignment) | ||||
|     _VARIABLES[id] = obj, type | ||||
|     obj.requires.append(assignment) | ||||
|     return obj | ||||
|  | ||||
|  | ||||
| def Pvariable(type, id, rhs): | ||||
|     lhs = RawExpression(u'{} *{}'.format(type if not SIMPLIFY else u'auto', id)) | ||||
|     rhs = safe_exp(rhs) | ||||
|     obj = MockObj(id, u'->') | ||||
|     add(AssignmentExpression(lhs, rhs, obj)) | ||||
|     assignment = AssignmentExpression(type, '*', id, rhs, obj) | ||||
|     add(assignment) | ||||
|     _VARIABLES[id] = obj, type | ||||
|     obj.requires.append(assignment) | ||||
|     return obj | ||||
|  | ||||
|  | ||||
| @@ -272,7 +306,6 @@ def get_variable(id, type=None): | ||||
|  | ||||
|         if result is None: | ||||
|             raise ESPHomeYAMLError(u"Couldn't find ID '{}' with type {}".format(id, type)) | ||||
|     result.usages += 1 | ||||
|     return result | ||||
|  | ||||
|  | ||||
| @@ -280,17 +313,17 @@ def add_task(func, config): | ||||
|     _QUEUE.append((func, config)) | ||||
|  | ||||
|  | ||||
| def add(expression): | ||||
| def add(expression, require=True): | ||||
|     if require and isinstance(expression, Expression): | ||||
|         expression.require() | ||||
|     _EXPRESSIONS.append(expression) | ||||
|     return expression | ||||
|  | ||||
|  | ||||
| class MockObj(Expression): | ||||
|     def __init__(self, base, op=u'.', parent=None): | ||||
|     def __init__(self, base, op=u'.'): | ||||
|         self.base = base | ||||
|         self.op = op | ||||
|         self.usages = 0 | ||||
|         self.parent = parent | ||||
|         super(MockObj, self).__init__() | ||||
|  | ||||
|     def __getattr__(self, attr): | ||||
| @@ -299,18 +332,26 @@ class MockObj(Expression): | ||||
|             attr = attr[1:] | ||||
|             next_op = u'->' | ||||
|         op = self.op | ||||
|         return MockObj(u'{}{}{}'.format(self.base, op, attr), next_op, self) | ||||
|         obj = MockObj(u'{}{}{}'.format(self.base, op, attr), next_op) | ||||
|         obj.requires.append(self) | ||||
|         return obj | ||||
|  | ||||
|     def __call__(self, *args, **kwargs): | ||||
|         self.usages += 1 | ||||
|         it = self.parent | ||||
|         while it is not None: | ||||
|             it.usages += 1 | ||||
|             it = it.parent | ||||
|         return CallExpression(self.base, *args) | ||||
|         call = CallExpression(self.base, *args) | ||||
|         obj = MockObj(call, self.op) | ||||
|         obj.requires.append(self) | ||||
|         obj.requires.append(call) | ||||
|         return obj | ||||
|  | ||||
|     def __str__(self): | ||||
|         return self.base | ||||
|         return unicode(self.base) | ||||
|  | ||||
|     def require(self): | ||||
|         self.required = True | ||||
|         for require in self.requires: | ||||
|             if require.required: | ||||
|                 continue | ||||
|             require.require() | ||||
|  | ||||
|  | ||||
| App = MockObj(u'App') | ||||
| @@ -358,13 +399,8 @@ def setup_mqtt_component(obj, config): | ||||
|         add(obj.set_custom_command_topic(config[CONF_COMMAND_TOPIC])) | ||||
|     if CONF_AVAILABILITY in config: | ||||
|         availability = config[CONF_AVAILABILITY] | ||||
|         exp = StructInitializer( | ||||
|             u'mqtt::Availability', | ||||
|             (u'topic', availability[CONF_TOPIC]), | ||||
|             (u'payload_available', availability[CONF_PAYLOAD_AVAILABLE]), | ||||
|             (u'payload_not_available', availability[CONF_PAYLOAD_NOT_AVAILABLE]), | ||||
|         ) | ||||
|         add(obj.set_availability(exp)) | ||||
|         add(obj.set_availability(availability[CONF_TOPIC], availability[CONF_PAYLOAD_AVAILABLE], | ||||
|                                  availability[CONF_PAYLOAD_NOT_AVAILABLE])) | ||||
|  | ||||
|  | ||||
| def exp_empty_optional(type): | ||||
|   | ||||
| @@ -1,13 +1,17 @@ | ||||
| from __future__ import print_function | ||||
|  | ||||
| import hashlib | ||||
| import logging | ||||
| from datetime import datetime | ||||
|  | ||||
| import paho.mqtt.client as mqtt | ||||
|  | ||||
| from esphomeyaml.const import CONF_BROKER, CONF_DISCOVERY_PREFIX, CONF_ESPHOMEYAML, CONF_LOGGER, \ | ||||
|     CONF_LOG_TOPIC, CONF_MQTT, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_TOPIC_PREFIX, \ | ||||
| from esphomeyaml import core | ||||
| from esphomeyaml.const import CONF_BROKER, CONF_DISCOVERY_PREFIX, CONF_ESPHOMEYAML, \ | ||||
|     CONF_LOG_TOPIC, \ | ||||
|     CONF_MQTT, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_TOPIC_PREFIX, \ | ||||
|     CONF_USERNAME | ||||
| from esphomeyaml.helpers import color | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| @@ -38,16 +42,21 @@ def initialize(config, subscriptions, on_message, username, password, client_id) | ||||
| def show_logs(config, topic=None, username=None, password=None, client_id=None): | ||||
|     if topic is not None: | ||||
|         pass  # already have topic | ||||
|     elif CONF_LOG_TOPIC in config.get(CONF_LOGGER, {}): | ||||
|         topic = config[CONF_LOGGER][CONF_LOG_TOPIC] | ||||
|     elif CONF_MQTT in config: | ||||
|         conf = config[CONF_MQTT] | ||||
|         if CONF_LOG_TOPIC in conf: | ||||
|             topic = config[CONF_MQTT][CONF_LOG_TOPIC] | ||||
|         elif CONF_TOPIC_PREFIX in config[CONF_MQTT]: | ||||
|             topic = config[CONF_MQTT][CONF_TOPIC_PREFIX] + u'/debug' | ||||
|         else: | ||||
|             topic = config[CONF_ESPHOMEYAML][CONF_NAME] + u'/debug' | ||||
|     else: | ||||
|         _LOGGER.error(u"MQTT isn't setup, can't start MQTT logs") | ||||
|         return 1 | ||||
|     _LOGGER.info(u"Starting log output from %s", topic) | ||||
|  | ||||
|     def on_message(client, userdata, msg): | ||||
|         time = datetime.now().time().strftime(u'[%H:%M:%S] ') | ||||
|         time = datetime.now().time().strftime(u'[%H:%M:%S]') | ||||
|         print(time + msg.payload) | ||||
|  | ||||
|     return initialize(config, [topic], on_message, username, password, client_id) | ||||
| @@ -67,3 +76,23 @@ def clear_topic(config, topic, username=None, password=None, client_id=None): | ||||
|         client.publish(msg.topic, None, retain=True) | ||||
|  | ||||
|     return initialize(config, [topic], on_message, username, password, client_id) | ||||
|  | ||||
|  | ||||
| # From marvinroger/async-mqtt-client -> scripts/get-fingerprint/get-fingerprint.py | ||||
| def get_fingerprint(config): | ||||
|     import ssl | ||||
|  | ||||
|     addr = config[CONF_MQTT][CONF_BROKER], config[CONF_MQTT][CONF_PORT] | ||||
|     _LOGGER.info("Getting fingerprint from %s:%s", addr[0], addr[1]) | ||||
|     try: | ||||
|         cert_pem = ssl.get_server_certificate(addr) | ||||
|     except IOError as err: | ||||
|         _LOGGER.error("Unable to connect to server: %s", err) | ||||
|         return 1 | ||||
|     cert_der = ssl.PEM_cert_to_DER_cert(cert_pem) | ||||
|  | ||||
|     sha1 = hashlib.sha1(cert_der).hexdigest() | ||||
|  | ||||
|     print(u"SHA1 Fingerprint: " + color('cyan', sha1)) | ||||
|     print(u"Copy above string into mqtt.ssl_fingerprints section of {}".format(core.CONFIG_PATH)) | ||||
|     return 0 | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import logging | ||||
| 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 | ||||
|  | ||||
| @@ -72,32 +73,32 @@ def _translate_pin(value): | ||||
|         pass | ||||
|     if value.startswith('GPIO'): | ||||
|         return vol.Coerce(int)(value[len('GPIO'):]) | ||||
|     if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|         if value in ESP32_PINS: | ||||
|             return ESP32_PINS[value] | ||||
|         if cv.BOARD not in ESP32_BOARD_TO_PINS: | ||||
|         if core.BOARD not in ESP32_BOARD_TO_PINS: | ||||
|             raise vol.Invalid(u"ESP32: Unknown board {} with unknown " | ||||
|                               u"pin {}.".format(cv.BOARD, value)) | ||||
|         if value not in ESP32_BOARD_TO_PINS[cv.BOARD]: | ||||
|                               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" | ||||
|                               u"pin {}".format(cv.BOARD, value)) | ||||
|         return ESP32_BOARD_TO_PINS[cv.BOARD][value] | ||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|                               u"pin {}".format(core.BOARD, value)) | ||||
|         return ESP32_BOARD_TO_PINS[core.BOARD][value] | ||||
|     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|         if value in ESP8266_PINS: | ||||
|             return ESP8266_PINS[value] | ||||
|         if cv.BOARD not in ESP8266_BOARD_TO_PINS: | ||||
|         if core.BOARD not in ESP8266_BOARD_TO_PINS: | ||||
|             raise vol.Invalid(u"ESP8266: Unknown board {} with unknown " | ||||
|                               u"pin {}.".format(cv.BOARD, value)) | ||||
|         if value not in ESP8266_BOARD_TO_PINS[cv.BOARD]: | ||||
|                               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" | ||||
|                               u"pin {}".format(cv.BOARD, value)) | ||||
|         return ESP8266_BOARD_TO_PINS[cv.BOARD][value] | ||||
|                               u"pin {}".format(core.BOARD, value)) | ||||
|         return ESP8266_BOARD_TO_PINS[core.BOARD][value] | ||||
|     raise vol.Invalid(u"Invalid ESP platform.") | ||||
|  | ||||
|  | ||||
| def _validate_gpio_pin(value): | ||||
|     value = _translate_pin(value) | ||||
|     if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|         if value < 0 or value > 39: | ||||
|             raise vol.Invalid(u"ESP32: Invalid pin number: {}".format(value)) | ||||
|         if 6 <= value <= 11: | ||||
| @@ -107,7 +108,7 @@ def _validate_gpio_pin(value): | ||||
|             _LOGGER.warning(u"ESP32: Pin %s (20, 24, 28-31) can usually not be used. " | ||||
|                             u"Be warned.", value) | ||||
|         return value | ||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|         if 6 <= value <= 11: | ||||
|             _LOGGER.warning(u"ESP8266: Pin %s (6-11) might already be used by the " | ||||
|                             u"flash interface. Be warned.", value) | ||||
| @@ -119,21 +120,21 @@ def _validate_gpio_pin(value): | ||||
|  | ||||
| def input_pin(value): | ||||
|     value = _validate_gpio_pin(value) | ||||
|     if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|         return value | ||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|         return value | ||||
|     raise vol.Invalid(u"Invalid ESP platform.") | ||||
|  | ||||
|  | ||||
| def output_pin(value): | ||||
|     value = _validate_gpio_pin(value) | ||||
|     if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|         if 34 <= value <= 39: | ||||
|             raise vol.Invalid(u"ESP32: Pin {} (34-39) can only be used as " | ||||
|                               u"input pins.".format(value)) | ||||
|         return value | ||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|         if value == 16: | ||||
|             raise vol.Invalid(u"Pin {} doesn't support output mode".format(value)) | ||||
|         return value | ||||
| @@ -142,11 +143,11 @@ def output_pin(value): | ||||
|  | ||||
| def analog_pin(value): | ||||
|     value = _validate_gpio_pin(value) | ||||
|     if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|         if 32 <= value <= 39:  # ADC1 | ||||
|             return value | ||||
|         raise vol.Invalid(u"ESP32: Only pins 32 though 39 support ADC.") | ||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|         if value == 17:  # A0 | ||||
|             return value | ||||
|         raise vol.Invalid(u"ESP8266: Only pin A0 (17) supports ADC.") | ||||
| @@ -171,9 +172,9 @@ PIN_MODES_ESP32 = [ | ||||
|  | ||||
| def pin_mode(value): | ||||
|     value = vol.All(vol.Coerce(str), vol.Upper)(value) | ||||
|     if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||
|         return vol.Any(*PIN_MODES_ESP32)(value) | ||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||
|         return vol.Any(*PIN_MODES_ESP8266)(value) | ||||
|     raise vol.Invalid(u"Invalid ESP platform.") | ||||
|  | ||||
| @@ -195,3 +196,14 @@ GPIO_INPUT_PIN_SCHEMA = vol.Any(input_pin, vol.Schema({ | ||||
|     vol.Optional(CONF_MODE): pin_mode, | ||||
|     vol.Optional(CONF_INVERTED): cv.boolean, | ||||
| })) | ||||
|  | ||||
|  | ||||
| def schema_validate_number(validator): | ||||
|     def valid(value): | ||||
|         if isinstance(value, dict): | ||||
|             value[CONF_NUMBER] = validator(value[CONF_NUMBER]) | ||||
|         else: | ||||
|             value = validator(value) | ||||
|         return value | ||||
|  | ||||
|     return valid | ||||
|   | ||||
| @@ -4,9 +4,9 @@ import codecs | ||||
| import errno | ||||
| import os | ||||
|  | ||||
| from esphomeyaml.config import get_component | ||||
| from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_LOGGER, \ | ||||
|     CONF_NAME, CONF_PLATFORM, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 | ||||
| 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 | ||||
| from esphomeyaml.core import ESPHomeYAMLError | ||||
|  | ||||
| CPP_AUTO_GENERATE_BEGIN = u'// ========== AUTO GENERATED CODE BEGIN ===========' | ||||
| @@ -52,7 +52,8 @@ framework = arduino | ||||
| lib_deps = | ||||
|     {esphomeyaml_uri} | ||||
|     ${{common.lib_deps}} | ||||
| build_flags ={build_flags} | ||||
| build_flags = | ||||
|     {build_flags} | ||||
|     ${{common.build_flags}} | ||||
| """ | ||||
|  | ||||
| @@ -62,18 +63,41 @@ PLATFORM_TO_PLATFORMIO = { | ||||
| } | ||||
|  | ||||
|  | ||||
| def get_build_flags(config, key): | ||||
|     build_flags = set() | ||||
|     for _, component, conf in iter_components(config): | ||||
|         if not hasattr(component, key): | ||||
|             continue | ||||
|         flags = getattr(component, key)(conf) | ||||
|         if flags is None: | ||||
|             continue | ||||
|         if isinstance(flags, (str, unicode)): | ||||
|             flags = [flags] | ||||
|         build_flags |= set(flags) | ||||
|     return build_flags | ||||
|  | ||||
|  | ||||
| def get_ini_content(config): | ||||
|     platform = config[CONF_ESPHOMEYAML][CONF_PLATFORM] | ||||
|     if platform in PLATFORM_TO_PLATFORMIO: | ||||
|         platform = PLATFORM_TO_PLATFORMIO[platform] | ||||
|     options = { | ||||
|         u'env': config[CONF_ESPHOMEYAML][CONF_NAME], | ||||
|         u'platform': PLATFORM_TO_PLATFORMIO[config[CONF_ESPHOMEYAML][CONF_PLATFORM]], | ||||
|         u'platform': platform, | ||||
|         u'board': config[CONF_ESPHOMEYAML][CONF_BOARD], | ||||
|         u'esphomeyaml_uri': config[CONF_ESPHOMEYAML][CONF_LIBRARY_URI], | ||||
|         u'build_flags': u'', | ||||
|     } | ||||
|     if CONF_LOGGER in config: | ||||
|         build_flags = get_component(CONF_LOGGER).get_build_flags(config[CONF_LOGGER]) | ||||
|     build_flags = set() | ||||
|     if config[CONF_ESPHOMEYAML][CONF_USE_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') | ||||
|  | ||||
|     # avoid changing build flags order | ||||
|     build_flags = sorted(list(build_flags)) | ||||
|     if build_flags: | ||||
|             options[u'build_flags'] = u'\n    ' + build_flags | ||||
|         options[u'build_flags'] = u'\n    '.join(build_flags) | ||||
|     return INI_CONTENT_FORMAT.format(**options) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| from __future__ import print_function | ||||
|  | ||||
| import codecs | ||||
| import fnmatch | ||||
| import logging | ||||
| from collections import OrderedDict | ||||
| import os | ||||
| from collections import OrderedDict | ||||
|  | ||||
| import yaml | ||||
|  | ||||
| @@ -79,9 +80,8 @@ def _ordered_dict(loader, node): | ||||
|  | ||||
|         if key in seen: | ||||
|             fname = getattr(loader.stream, 'name', '') | ||||
|             _LOGGER.error( | ||||
|                 u'YAML file %s contains duplicate key "%s". ' | ||||
|                 u'Check lines %d and %d.', fname, key, seen[key], line) | ||||
|             raise ESPHomeYAMLError(u'YAML file {} contains duplicate key "{}". ' | ||||
|                                    u'Check lines {} and {}.'.format(fname, key, seen[key], line)) | ||||
|         seen[key] = line | ||||
|  | ||||
|     return _add_reference(OrderedDict(nodes), loader, node) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user