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 random | ||||||
| import sys | import sys | ||||||
|  |  | ||||||
| from esphomeyaml import helpers, mqtt, writer, yaml_util, wizard | from esphomeyaml import core, mqtt, wizard, writer, yaml_util, const | ||||||
| from esphomeyaml.config import add_component_task, read_config | from esphomeyaml.config import core_to_code, get_component, iter_components, read_config | ||||||
| from esphomeyaml.const import CONF_ESPHOMEYAML, CONF_HOSTNAME, CONF_MANUAL_IP, CONF_NAME, \ | from esphomeyaml.const import CONF_BAUD_RATE, CONF_ESPHOMEYAML, CONF_HOSTNAME, CONF_LOGGER, \ | ||||||
|     CONF_STATIC_IP, \ |     CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI | ||||||
|     CONF_WIFI, CONF_LOGGER, CONF_BAUD_RATE | from esphomeyaml.helpers import AssignmentExpression, RawStatement, _EXPRESSIONS, add, add_task, \ | ||||||
| from esphomeyaml.helpers import AssignmentExpression, RawStatement, _EXPRESSIONS, add, \ |     color, get_variable, indent, quote, statement, Expression | ||||||
|     get_variable, indent, quote, statement, color |  | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ota', 'mqtt', 'i2c'] | PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ota', 'mqtt', 'web_server', 'i2c'] | ||||||
|  |  | ||||||
| CONFIG_PATH = None |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def get_name(config): | def get_name(config): | ||||||
| @@ -26,7 +23,7 @@ def get_name(config): | |||||||
|  |  | ||||||
|  |  | ||||||
| def get_base_path(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(): | def discover_serial_ports(): | ||||||
| @@ -47,8 +44,6 @@ def discover_serial_ports(): | |||||||
|  |  | ||||||
|     if not result: |     if not result: | ||||||
|         return None |         return None | ||||||
|     if len(result) == 1: |  | ||||||
|         return result[0] |  | ||||||
|     print(u"Found multiple serial port options, please choose one:") |     print(u"Found multiple serial port options, please choose one:") | ||||||
|     for i, (res, desc) in enumerate(zip(result, descs)): |     for i, (res, desc) in enumerate(zip(result, descs)): | ||||||
|         print(u"  [{}] {} ({})".format(i, res, desc)) |         print(u"  [{}] {} ({})".format(i, res, desc)) | ||||||
| @@ -107,18 +102,24 @@ def run_miniterm(config, port): | |||||||
|  |  | ||||||
| def write_cpp(config): | def write_cpp(config): | ||||||
|     _LOGGER.info("Generating C++ source...") |     _LOGGER.info("Generating C++ source...") | ||||||
|  |  | ||||||
|  |     add_task(core_to_code, config[CONF_ESPHOMEYAML]) | ||||||
|     for domain in PRE_INITIALIZE: |     for domain in PRE_INITIALIZE: | ||||||
|  |         if domain == CONF_ESPHOMEYAML: | ||||||
|  |             continue | ||||||
|         if domain in config: |         if domain in config: | ||||||
|             add_component_task(domain, config[domain]) |             add_task(get_component(domain).to_code, config[domain]) | ||||||
|  |  | ||||||
|     # Clear queue |     # Clear queue | ||||||
|     get_variable(None) |     get_variable(None) | ||||||
|     add(RawStatement('')) |     add(RawStatement('')) | ||||||
|  |  | ||||||
|     for domain, conf in config.iteritems(): |     for domain, component, conf in iter_components(config): | ||||||
|         if domain in PRE_INITIALIZE: |         if domain in PRE_INITIALIZE: | ||||||
|             continue |             continue | ||||||
|         add_component_task(domain, conf) |         if not hasattr(component, 'to_code'): | ||||||
|  |             continue | ||||||
|  |         add_task(component.to_code, conf) | ||||||
|  |  | ||||||
|     # Clear queue |     # Clear queue | ||||||
|     get_variable(None) |     get_variable(None) | ||||||
| @@ -127,8 +128,11 @@ def write_cpp(config): | |||||||
|  |  | ||||||
|     all_code = [] |     all_code = [] | ||||||
|     for exp in _EXPRESSIONS: |     for exp in _EXPRESSIONS: | ||||||
|         if helpers.SIMPLIFY and isinstance(exp, AssignmentExpression) and exp.obj.usages == 0: |         if core.SIMPLIFY: | ||||||
|             exp = exp.rhs |             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))) |         all_code.append(unicode(statement(exp))) | ||||||
|  |  | ||||||
|     platformio_ini_s = writer.get_ini_content(config) |     platformio_ini_s = writer.get_ini_content(config) | ||||||
| @@ -211,8 +215,6 @@ def setup_log(): | |||||||
|  |  | ||||||
|  |  | ||||||
| def main(): | def main(): | ||||||
|     global CONFIG_PATH |  | ||||||
|  |  | ||||||
|     setup_log() |     setup_log() | ||||||
|  |  | ||||||
|     parser = argparse.ArgumentParser(prog='esphomeyaml') |     parser = argparse.ArgumentParser(prog='esphomeyaml') | ||||||
| @@ -260,13 +262,17 @@ def main(): | |||||||
|     subparsers.add_parser('wizard', help="A helpful setup wizard that will guide " |     subparsers.add_parser('wizard', help="A helpful setup wizard that will guide " | ||||||
|                                          "you through setting up esphomeyaml.") |                                          "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() |     args = parser.parse_args() | ||||||
|  |  | ||||||
|     if args.command == 'wizard': |     if args.command == 'wizard': | ||||||
|         return wizard.wizard(args.configuration) |         return wizard.wizard(args.configuration) | ||||||
|  |  | ||||||
|     CONFIG_PATH = args.configuration |     core.CONFIG_PATH = args.configuration | ||||||
|     config = read_config(CONFIG_PATH) |  | ||||||
|  |     config = read_config(core.CONFIG_PATH) | ||||||
|     if config is None: |     if config is None: | ||||||
|         return 1 |         return 1 | ||||||
|  |  | ||||||
| @@ -294,6 +300,8 @@ def main(): | |||||||
|         return show_logs(config, args, port) |         return show_logs(config, args, port) | ||||||
|     elif args.command == 'clean-mqtt': |     elif args.command == 'clean-mqtt': | ||||||
|         return clean_mqtt(config, args) |         return clean_mqtt(config, args) | ||||||
|  |     elif args.command == 'mqtt-fingerprint': | ||||||
|  |         return mqtt.get_fingerprint(config) | ||||||
|     elif args.command == 'run': |     elif args.command == 'run': | ||||||
|         exit_code = write_cpp(config) |         exit_code = write_cpp(config) | ||||||
|         if exit_code != 0: |         if exit_code != 0: | ||||||
| @@ -302,14 +310,17 @@ def main(): | |||||||
|         if exit_code != 0: |         if exit_code != 0: | ||||||
|             return exit_code |             return exit_code | ||||||
|         _LOGGER.info(u"Successfully compiled program.") |         _LOGGER.info(u"Successfully compiled program.") | ||||||
|         if args.no_logs: |  | ||||||
|             return 0 |  | ||||||
|         port = args.upload_port or discover_serial_ports() |         port = args.upload_port or discover_serial_ports() | ||||||
|         exit_code = upload_program(config, args, port) |         exit_code = upload_program(config, args, port) | ||||||
|         if exit_code != 0: |         if exit_code != 0: | ||||||
|             return exit_code |             return exit_code | ||||||
|         _LOGGER.info(u"Successfully uploaded program.") |         _LOGGER.info(u"Successfully uploaded program.") | ||||||
|  |         if args.no_logs: | ||||||
|  |             return 0 | ||||||
|         return show_logs(config, args, port) |         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)) |     print(u"Unknown command {}".format(args.command)) | ||||||
|     return 1 |     return 1 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,3 +35,7 @@ def to_code(config): | |||||||
|         ads1115 = Pvariable(ADS1115_COMPONENT_CLASS, conf[CONF_ID], rhs) |         ads1115 = Pvariable(ADS1115_COMPONENT_CLASS, conf[CONF_ID], rhs) | ||||||
|         if CONF_RATE in conf: |         if CONF_RATE in conf: | ||||||
|             add(ads1115.set_rate(RawExpression(RATES[conf[CONF_RATE]]))) |             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.const import CONF_DEVICE_CLASS, CONF_INVERTED | ||||||
| from esphomeyaml.helpers import add, setup_mqtt_component | from esphomeyaml.helpers import add, setup_mqtt_component | ||||||
|  |  | ||||||
| PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ |  | ||||||
|     vol.Optional(CONF_INVERTED): cv.boolean, |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| DEVICE_CLASSES = [ | DEVICE_CLASSES = [ | ||||||
|     '', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas', |     '', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas', | ||||||
|     'heat', 'light', 'lock', 'moisture', 'motion', 'moving', 'occupancy', |     '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)) | 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.Optional(CONF_DEVICE_CLASS): vol.All(vol.Lower, | ||||||
|                                              vol.Any(*DEVICE_CLASSES, msg=DEVICE_CLASSES_MSG)), |                                              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])) |         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) |     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 | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml import pins | from esphomeyaml import pins | ||||||
| from esphomeyaml.components import binary_sensor | 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 | from esphomeyaml.helpers import App, add, exp_gpio_input_pin, variable | ||||||
|  |  | ||||||
| PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ | PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ | ||||||
| @@ -13,9 +13,13 @@ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ | |||||||
|  |  | ||||||
|  |  | ||||||
| def to_code(config): | def to_code(config): | ||||||
|     rhs = App.make_gpio_binary_sensor(exp_gpio_input_pin(config[CONF_PIN]), |     rhs = App.make_gpio_binary_sensor(config[CONF_NAME], exp_gpio_input_pin(config[CONF_PIN])) | ||||||
|                                       config[CONF_NAME], config.get(CONF_DEVICE_CLASS)) |     gpio = variable('Application::MakeGPIOBinarySensor', config[CONF_ID], rhs) | ||||||
|     gpio = variable('Application::SimpleBinarySensor', config[CONF_ID], rhs) |  | ||||||
|     if CONF_INVERTED in config: |     if CONF_INVERTED in config: | ||||||
|         add(gpio.Pgpio.set_inverted(config[CONF_INVERTED])) |         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 | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.components import binary_sensor | from esphomeyaml.components import binary_sensor | ||||||
| from esphomeyaml.const import CONF_ID, CONF_NAME | 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({ | PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ | ||||||
|     cv.GenerateID('status_binary_sensor'): cv.register_variable_id, |     cv.GenerateID('status_binary_sensor'): cv.register_variable_id, | ||||||
| @@ -10,5 +12,10 @@ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ | |||||||
|  |  | ||||||
| def to_code(config): | def to_code(config): | ||||||
|     rhs = App.make_status_binary_sensor(config[CONF_NAME]) |     rhs = App.make_status_binary_sensor(config[CONF_NAME]) | ||||||
|     gpio = Pvariable('binary_sensor::MQTTBinarySensorComponent', config[CONF_ID], rhs) |     status = variable('Application::MakeStatusBinarySensor', config[CONF_ID], rhs) | ||||||
|     binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config) |     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: |     for conf in config: | ||||||
|         rhs = App.make_dallas_component(conf[CONF_PIN], conf.get(CONF_UPDATE_INTERVAL)) |         rhs = App.make_dallas_component(conf[CONF_PIN], conf.get(CONF_UPDATE_INTERVAL)) | ||||||
|         Pvariable(DALLAS_COMPONENT_CLASS, conf[CONF_ID], rhs) |         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: |     if CONF_SPEED_COMMAND_TOPIC in config: | ||||||
|         add(obj.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC])) |         add(obj.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC])) | ||||||
|     setup_mqtt_component(obj, config) |     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): | def to_code(config): | ||||||
|     output = get_variable(config[CONF_OUTPUT]) |     output = get_variable(config[CONF_OUTPUT]) | ||||||
|     rhs = App.make_fan(config[CONF_NAME]) |     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)) |     add(fan_struct.Poutput.set_binary(output)) | ||||||
|     if CONF_OSCILLATION_OUTPUT in config: |     if CONF_OSCILLATION_OUTPUT in config: | ||||||
|         oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT]) |         oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT]) | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({ | |||||||
| def to_code(config): | def to_code(config): | ||||||
|     output = get_variable(config[CONF_OUTPUT]) |     output = get_variable(config[CONF_OUTPUT]) | ||||||
|     rhs = App.make_fan(config[CONF_NAME]) |     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: |     if CONF_SPEED in config: | ||||||
|         speeds = config[CONF_SPEED] |         speeds = config[CONF_SPEED] | ||||||
|         add(fan_struct.Poutput.set_speed(output, 0.0, |         add(fan_struct.Poutput.set_speed(output, 0.0, | ||||||
|   | |||||||
| @@ -14,3 +14,7 @@ CONFIG_SCHEMA = vol.Schema({ | |||||||
|  |  | ||||||
| def to_code(config): | def to_code(config): | ||||||
|     add(App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_FREQUENCY))) |     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]) |         pin = exp_gpio_output_pin(conf[CONF_PIN]) | ||||||
|         rhs = App.make_ir_transmitter(pin, conf.get(CONF_CARRIER_DUTY_PERCENT)) |         rhs = App.make_ir_transmitter(pin, conf.get(CONF_CARRIER_DUTY_PERCENT)) | ||||||
|         Pvariable(IR_TRANSMITTER_COMPONENT_CLASS, conf[CONF_ID], rhs) |         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 | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH | 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({ | PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | ||||||
|  |  | ||||||
| }).extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA.schema) | }).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: |     if CONF_DEFAULT_TRANSITION_LENGTH in config: | ||||||
|         add(obj.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH])) |         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 | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.components import light | from esphomeyaml.components import light | ||||||
| from esphomeyaml.const import CONF_ID, CONF_NAME, CONF_OUTPUT | 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({ | PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||||
|     cv.GenerateID('binary_light'): cv.register_variable_id, |     cv.GenerateID('binary_light'): cv.register_variable_id, | ||||||
| @@ -15,5 +15,6 @@ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | |||||||
| def to_code(config): | def to_code(config): | ||||||
|     output = get_variable(config[CONF_OUTPUT]) |     output = get_variable(config[CONF_OUTPUT]) | ||||||
|     rhs = App.make_binary_light(config[CONF_NAME], output) |     rhs = App.make_binary_light(config[CONF_NAME], output) | ||||||
|     light_struct = variable('Application::LightStruct', config[CONF_ID], rhs) |     light_struct = variable('Application::MakeLight', config[CONF_ID], rhs) | ||||||
|     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.components import light | ||||||
| from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, \ | from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, \ | ||||||
|     CONF_NAME, CONF_OUTPUT |     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({ | PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||||
|     cv.GenerateID('monochromatic_light'): cv.register_variable_id, |     cv.GenerateID('monochromatic_light'): cv.register_variable_id, | ||||||
| @@ -17,7 +17,8 @@ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | |||||||
| def to_code(config): | def to_code(config): | ||||||
|     output = get_variable(config[CONF_OUTPUT]) |     output = get_variable(config[CONF_OUTPUT]) | ||||||
|     rhs = App.make_monochromatic_light(config[CONF_NAME], 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: |     if CONF_GAMMA_CORRECT in config: | ||||||
|         add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT])) |         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.components import light | ||||||
| from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ | from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ | ||||||
|     CONF_GREEN, CONF_ID, CONF_NAME, CONF_RED |     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({ | PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||||
|     cv.GenerateID('rgb_light'): cv.register_variable_id, |     cv.GenerateID('rgb_light'): cv.register_variable_id, | ||||||
| @@ -21,7 +21,8 @@ def to_code(config): | |||||||
|     green = get_variable(config[CONF_GREEN]) |     green = get_variable(config[CONF_GREEN]) | ||||||
|     blue = get_variable(config[CONF_BLUE]) |     blue = get_variable(config[CONF_BLUE]) | ||||||
|     rhs = App.make_rgb_light(config[CONF_NAME], red, green, 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: |     if CONF_GAMMA_CORRECT in config: | ||||||
|         add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT])) |         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.components import light | ||||||
| from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ | from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ | ||||||
|     CONF_GREEN, CONF_ID, CONF_NAME, CONF_RED, CONF_WHITE |     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({ | PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ | ||||||
|     cv.GenerateID('rgbw_light'): cv.register_variable_id, |     cv.GenerateID('rgbw_light'): cv.register_variable_id, | ||||||
| @@ -23,7 +23,8 @@ def to_code(config): | |||||||
|     blue = get_variable(config[CONF_BLUE]) |     blue = get_variable(config[CONF_BLUE]) | ||||||
|     white = get_variable(config[CONF_WHITE]) |     white = get_variable(config[CONF_WHITE]) | ||||||
|     rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, 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: |     if CONF_GAMMA_CORRECT in config: | ||||||
|         add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT])) |         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 | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGGER, CONF_LOGS, \ | from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGGER, CONF_LOGS, \ | ||||||
|     CONF_LOG_TOPIC, CONF_TX_BUFFER_SIZE |     CONF_TX_BUFFER_SIZE | ||||||
| from esphomeyaml.core import ESPHomeYAMLError | 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'] | LOG_LEVELS = ['NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE'] | ||||||
|  |  | ||||||
|  |  | ||||||
| # pylint: disable=invalid-name | # pylint: disable=invalid-name | ||||||
| is_log_level = vol.All(vol.Upper, vol.Any(*LOG_LEVELS)) | 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, |     cv.GenerateID(CONF_LOGGER): cv.register_variable_id, | ||||||
|     vol.Optional(CONF_BAUD_RATE): cv.positive_int, |     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_TX_BUFFER_SIZE): cv.positive_int, | ||||||
|     vol.Optional(CONF_LEVEL): is_log_level, |     vol.Optional(CONF_LEVEL): is_log_level, | ||||||
|     vol.Optional(CONF_LOGS): vol.Schema({ |     vol.Optional(CONF_LOGS): vol.Schema({ | ||||||
| @@ -33,16 +31,7 @@ def exp_log_level(level): | |||||||
|  |  | ||||||
|  |  | ||||||
| def to_code(config): | def to_code(config): | ||||||
|     baud_rate = config.get(CONF_BAUD_RATE) |     rhs = App.init_log(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) |  | ||||||
|     log = Pvariable(u'LogComponent', config[CONF_ID], rhs) |     log = Pvariable(u'LogComponent', config[CONF_ID], rhs) | ||||||
|     if CONF_TX_BUFFER_SIZE in config: |     if CONF_TX_BUFFER_SIZE in config: | ||||||
|         add(log.set_tx_buffer_size(config[CONF_TX_BUFFER_SIZE])) |         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))) |         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: |     if CONF_LEVEL in config: | ||||||
|         return u'-DESPHOMELIB_LOG_LEVEL={}'.format(esphomelib_log_level(config[CONF_LEVEL])) |         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 voluptuous as vol | ||||||
|  |  | ||||||
| import esphomeyaml.config_validation as cv | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_DISCOVERY, \ | from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, CONF_DISCOVERY, \ | ||||||
|     CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_MQTT, CONF_PASSWORD, \ |     CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_SSL_FINGERPRINTS, CONF_ID, CONF_LOG_TOPIC, \ | ||||||
|     CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_USERNAME, \ |     CONF_MQTT, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, CONF_TOPIC, \ | ||||||
|     CONF_WILL_MESSAGE, CONF_CLIENT_ID |     CONF_TOPIC_PREFIX, CONF_USERNAME, CONF_WILL_MESSAGE | ||||||
| from esphomeyaml.helpers import App, Pvariable, StructInitializer, add, exp_empty_optional | from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, StructInitializer, add, \ | ||||||
|  |     exp_empty_optional, RawExpression | ||||||
|  |  | ||||||
| MQTT_WILL_BIRTH_SCHEMA = vol.Any(None, vol.Schema({ | MQTT_WILL_BIRTH_SCHEMA = vol.Any(None, vol.Schema({ | ||||||
|     vol.Required(CONF_TOPIC): cv.publish_topic, |     vol.Required(CONF_TOPIC): cv.publish_topic, | ||||||
| @@ -19,7 +22,7 @@ def validate_broker(value): | |||||||
|     value = cv.string_strict(value) |     value = cv.string_strict(value) | ||||||
|     if value.endswith(u'.local'): |     if value.endswith(u'.local'): | ||||||
|         raise vol.Invalid(u"MQTT server addresses ending with '.local' are currently unsupported." |         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: |     if u':' in value: | ||||||
|         raise vol.Invalid(u"Please specify the port using the port: option") |         raise vol.Invalid(u"Please specify the port using the port: option") | ||||||
|     if not value: |     if not value: | ||||||
| @@ -27,7 +30,14 @@ def validate_broker(value): | |||||||
|     return 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, |     cv.GenerateID(CONF_MQTT): cv.register_variable_id, | ||||||
|     vol.Required(CONF_BROKER): validate_broker, |     vol.Required(CONF_BROKER): validate_broker, | ||||||
|     vol.Optional(CONF_PORT, default=1883): cv.port, |     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_BIRTH_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, | ||||||
|     vol.Optional(CONF_WILL_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_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])) |         add(mqtt.set_topic_prefix(config[CONF_TOPIC_PREFIX])) | ||||||
|     if CONF_CLIENT_ID in config: |     if CONF_CLIENT_ID in config: | ||||||
|         add(mqtt.set_client_id(config[CONF_CLIENT_ID])) |         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 voluptuous as vol | ||||||
|  |  | ||||||
| import esphomeyaml.config_validation as cv | 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, \ | 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.core import ESPHomeYAMLError | ||||||
| from esphomeyaml.helpers import App, Pvariable, add | from esphomeyaml.helpers import App, Pvariable, add | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = cv.ID_SCHEMA.extend({ | CONFIG_SCHEMA = vol.Schema({ | ||||||
|     cv.GenerateID(CONF_OTA): cv.register_variable_id, |     cv.GenerateID(CONF_OTA): cv.register_variable_id, | ||||||
|     vol.Optional(CONF_SAFE_MODE, default=True): cv.boolean, |     vol.Optional(CONF_SAFE_MODE, default=True): cv.boolean, | ||||||
|     # TODO Num attempts + wait time |     # TODO Num attempts + wait time | ||||||
| @@ -33,12 +34,16 @@ def to_code(config): | |||||||
| def get_port(config): | def get_port(config): | ||||||
|     if CONF_PORT in config[CONF_OTA]: |     if CONF_PORT in config[CONF_OTA]: | ||||||
|         return config[CONF_OTA][CONF_PORT] |         return config[CONF_OTA][CONF_PORT] | ||||||
|     if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32: |     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||||
|         return 3232 |         return 3232 | ||||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: |     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||||
|         return 8266 |         return 8266 | ||||||
|     raise ESPHomeYAMLError(u"Invalid ESP Platform for ESP OTA port.") |     raise ESPHomeYAMLError(u"Invalid ESP Platform for ESP OTA port.") | ||||||
|  |  | ||||||
|  |  | ||||||
| def get_auth(config): | def get_auth(config): | ||||||
|     return config[CONF_OTA].get(CONF_PASSWORD, '') |     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)) |         add(obj.set_power_supply(power_supply)) | ||||||
|     if CONF_MAX_POWER in config: |     if CONF_MAX_POWER in config: | ||||||
|         add(obj.set_max_power(config[CONF_MAX_POWER])) |         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 import pins | ||||||
| from esphomeyaml.components import output | from esphomeyaml.components import output | ||||||
| from esphomeyaml.const import CONF_ID, CONF_PIN, \ | from esphomeyaml.const import CONF_ID, CONF_PIN, ESP_PLATFORM_ESP8266 | ||||||
|     ESP_PLATFORM_ESP8266 |  | ||||||
| from esphomeyaml.core import ESPHomeYAMLError | 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] | 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({ | 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): | 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]) |     pin = exp_gpio_output_pin(config[CONF_PIN]) | ||||||
|     rhs = App.make_esp8266_pwm_output(pin) |     rhs = App.make_esp8266_pwm_output(pin) | ||||||
|     gpio = Pvariable('output::ESP8266PWMOutput', config[CONF_ID], rhs) |     gpio = Pvariable('output::ESP8266PWMOutput', config[CONF_ID], rhs) | ||||||
|     output.setup_output_platform(gpio, config) |     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) |     rhs = App.make_gpio_output(pin) | ||||||
|     gpio = Pvariable('output::GPIOBinaryOutputComponent', config[CONF_ID], rhs) |     gpio = Pvariable('output::GPIOBinaryOutputComponent', config[CONF_ID], rhs) | ||||||
|     output.setup_output_platform(gpio, config) |     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: |     if CONF_CHANNEL in config: | ||||||
|         add(ledc.set_channel(config[CONF_CHANNEL])) |         add(ledc.set_channel(config[CONF_CHANNEL])) | ||||||
|     output.setup_output_platform(ledc, config) |     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) |     rhs = pca9685.create_channel(config[CONF_CHANNEL], power_supply) | ||||||
|     out = Pvariable('output::PCA9685OutputComponent::Channel', config[CONF_ID], rhs) |     out = Pvariable('output::PCA9685OutputComponent::Channel', config[CONF_ID], rhs) | ||||||
|     output.setup_output_platform(out, config, skip_power_supply=True) |     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( |             phase_balancer = RawExpression(u'PCA9685_PhaseBalancer_{}'.format( | ||||||
|                 conf[CONF_PHASE_BALANCER])) |                 conf[CONF_PHASE_BALANCER])) | ||||||
|             add(pca9685.set_phase_balancer(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])) |             add(psu.set_enable_time(conf[CONF_ENABLE_TIME])) | ||||||
|         if CONF_KEEP_ON_TIME in conf: |         if CONF_KEEP_ON_TIME in conf: | ||||||
|             add(psu.set_keep_on_time(conf[CONF_KEEP_ON_TIME])) |             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 | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.const import CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_EXPIRE_AFTER, \ | 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_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_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_SLIDING_WINDOW_MOVING_AVERAGE, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE, CONF_ID | ||||||
| from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add, \ | from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add, \ | ||||||
|     setup_mqtt_component |     setup_mqtt_component | ||||||
|  |  | ||||||
| @@ -13,7 +13,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | |||||||
| }) | }) | ||||||
|  |  | ||||||
| FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.Any( | 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_OFFSET): vol.Coerce(float)}), | ||||||
|     vol.Schema({vol.Required(CONF_MULTIPLY): vol.Coerce(float)}), |     vol.Schema({vol.Required(CONF_MULTIPLY): vol.Coerce(float)}), | ||||||
|     vol.Schema({vol.Required(CONF_FILTER_OUT): 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({ | 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 | # pylint: disable=invalid-name | ||||||
| @@ -72,30 +71,38 @@ def setup_filter(config): | |||||||
|         conf = config[CONF_EXPONENTIAL_MOVING_AVERAGE] |         conf = config[CONF_EXPONENTIAL_MOVING_AVERAGE] | ||||||
|         return ExponentialMovingAverageFilter(conf[CONF_ALPHA], conf[CONF_SEND_EVERY]) |         return ExponentialMovingAverageFilter(conf[CONF_ALPHA], conf[CONF_SEND_EVERY]) | ||||||
|     if CONF_LAMBDA in config: |     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)) |         return LambdaFilter(RawExpression(s)) | ||||||
|     raise ValueError("Filter unsupported: {}".format(config)) |     raise ValueError(u"Filter unsupported: {}".format(config)) | ||||||
|  |  | ||||||
|  |  | ||||||
| def setup_mqtt_sensor_component(obj, 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: |     if CONF_UNIT_OF_MEASUREMENT in config: | ||||||
|         add(obj.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT])) |         add(obj.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT])) | ||||||
|     if CONF_ICON in config: |     if CONF_ICON in config: | ||||||
|         add(obj.set_icon(config[CONF_ICON])) |         add(obj.set_icon(config[CONF_ICON])) | ||||||
|     if CONF_ACCURACY_DECIMALS in config: |     if CONF_ACCURACY_DECIMALS in config: | ||||||
|         add(obj.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS])) |         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: |     if CONF_FILTERS in config: | ||||||
|         filters = [setup_filter(x) for x in config[CONF_FILTERS]] |         filters = [setup_filter(x) for x in config[CONF_FILTERS]] | ||||||
|         add(obj.set_filters(ArrayInitializer(*filters))) |         add(obj.set_filters(ArrayInitializer(*filters))) | ||||||
|     setup_mqtt_component(obj, config) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def make_mqtt_sensor_for(exp, config): | def register_sensor(var, config): | ||||||
|     rhs = App.make_mqtt_sensor_for(exp, config[CONF_NAME]) |     setup_sensor(var, config) | ||||||
|     mqtt_sensor = Pvariable('sensor::MQTTSensorComponent', config[CONF_ID], rhs) |     rhs = App.register_sensor(var) | ||||||
|  |     mqtt_sensor = Pvariable('sensor::MQTTSensorComponent', config[CONF_MQTT_ID], rhs) | ||||||
|     setup_mqtt_sensor_component(mqtt_sensor, config) |     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): | 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)) |                               config.get(CONF_UPDATE_INTERVAL)) | ||||||
|     make = variable('Application::MakeADCSensor', config[CONF_ID], rhs) |     make = variable('Application::MakeADCSensor', config[CONF_ID], rhs) | ||||||
|     adc = make.Padc |     adc = make.Padc | ||||||
|     if CONF_ATTENUATION in config: |     if CONF_ATTENUATION in config: | ||||||
|         attenuation = ATTENUATION_MODES[config[CONF_ATTENUATION]] |         attenuation = ATTENUATION_MODES[config[CONF_ATTENUATION]] | ||||||
|         add(adc.set_attenuation(RawExpression(attenuation))) |         add(adc.set_attenuation(RawExpression(attenuation))) | ||||||
|  |     sensor.setup_sensor(adc, config) | ||||||
|     sensor.setup_mqtt_sensor_component(make.Pmqtt, 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 | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.components import sensor | from esphomeyaml.components import sensor | ||||||
| from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_UPDATE_INTERVAL | from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_UPDATE_INTERVAL, \ | ||||||
| from esphomeyaml.helpers import get_variable, RawExpression |     CONF_NAME, CONF_ID | ||||||
|  | from esphomeyaml.helpers import RawExpression, get_variable, Pvariable | ||||||
|  |  | ||||||
| DEPENDENCIES = ['ads1115'] | DEPENDENCIES = ['ads1115'] | ||||||
|  |  | ||||||
| @@ -40,6 +41,7 @@ def validate_gain(value): | |||||||
|  |  | ||||||
|  |  | ||||||
| PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ | 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_MULTIPLEXER): vol.All(vol.Upper, vol.Any(*list(MUX.keys()))), | ||||||
|     vol.Required(CONF_GAIN): validate_gain, |     vol.Required(CONF_GAIN): validate_gain, | ||||||
|     vol.Optional(CONF_ADS1115_ID): cv.variable_id, |     vol.Optional(CONF_ADS1115_ID): cv.variable_id, | ||||||
| @@ -52,5 +54,10 @@ def to_code(config): | |||||||
|  |  | ||||||
|     mux = RawExpression(MUX[config[CONF_MULTIPLEXER]]) |     mux = RawExpression(MUX[config[CONF_MULTIPLEXER]]) | ||||||
|     gain = RawExpression(GAIN[config[CONF_GAIN]]) |     gain = RawExpression(GAIN[config[CONF_GAIN]]) | ||||||
|     sensor_ = hub.get_sensor(mux, gain, config.get(CONF_UPDATE_INTERVAL)) |     rhs = hub.get_sensor(config[CONF_NAME], mux, gain, config.get(CONF_UPDATE_INTERVAL)) | ||||||
|     sensor.make_mqtt_sensor_for(sensor_, config) |     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], |     rhs = App.make_bmp085_sensor(config[CONF_TEMPERATURE][CONF_NAME], | ||||||
|                                  config[CONF_PRESSURE][CONF_NAME], |                                  config[CONF_PRESSURE][CONF_NAME], | ||||||
|                                  config.get(CONF_UPDATE_INTERVAL)) |                                  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: |     if CONF_ADDRESS in config: | ||||||
|         add(bmp.Pbmp.set_address(HexIntLiteral(config[CONF_ADDRESS]))) |         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_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]) |     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 | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.components import sensor | from esphomeyaml.components import sensor | ||||||
| from esphomeyaml.components.dallas import DALLAS_COMPONENT_CLASS | from esphomeyaml.components.dallas import DALLAS_COMPONENT_CLASS | ||||||
| from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_RESOLUTION, \ | from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_NAME, \ | ||||||
|     CONF_UPDATE_INTERVAL |     CONF_RESOLUTION, \ | ||||||
| from esphomeyaml.helpers import HexIntLiteral, get_variable |     CONF_UPDATE_INTERVAL, CONF_ID | ||||||
|  | from esphomeyaml.helpers import HexIntLiteral, get_variable, Pvariable | ||||||
|  |  | ||||||
| PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ | 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_ADDRESS, 'dallas'): cv.hex_int, | ||||||
|     vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int, |     vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int, | ||||||
|     vol.Optional(CONF_DALLAS_ID): cv.variable_id, |     vol.Optional(CONF_DALLAS_ID): cv.variable_id, | ||||||
| @@ -23,9 +25,14 @@ def to_code(config): | |||||||
|  |  | ||||||
|     if CONF_ADDRESS in config: |     if CONF_ADDRESS in config: | ||||||
|         address = HexIntLiteral(config[CONF_ADDRESS]) |         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)) |                                          config.get(CONF_RESOLUTION)) | ||||||
|     else: |     else: | ||||||
|         sensor_ = hub.Pget_sensor_by_index(config[CONF_INDEX], update_interval, |         rhs = hub.Pget_sensor_by_index(config[CONF_NAME], config[CONF_INDEX], | ||||||
|                                            config.get(CONF_RESOLUTION)) |                                        update_interval, config.get(CONF_RESOLUTION)) | ||||||
|     sensor.make_mqtt_sensor_for(sensor_, config) |     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): | def to_code(config): | ||||||
|     rhs = App.make_dht_sensor(config[CONF_PIN], config[CONF_TEMPERATURE][CONF_NAME], |     rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME], | ||||||
|                               config[CONF_HUMIDITY][CONF_NAME], config.get(CONF_UPDATE_INTERVAL)) |                               config[CONF_HUMIDITY][CONF_NAME], | ||||||
|     dht = variable('Application::MakeDHTComponent', config[CONF_ID], rhs) |                               config[CONF_PIN], config.get(CONF_UPDATE_INTERVAL)) | ||||||
|  |     dht = variable('Application::MakeDHTSensor', config[CONF_ID], rhs) | ||||||
|     if CONF_MODEL in config: |     if CONF_MODEL in config: | ||||||
|         model = RawExpression('DHT::{}'.format(config[CONF_MODEL])) |         model = RawExpression('DHT::{}'.format(config[CONF_MODEL])) | ||||||
|         add(dht.Pdht.set_dht_model(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_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]) |     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], |     rhs = App.make_hdc1080_sensor(config[CONF_TEMPERATURE][CONF_NAME], | ||||||
|                                   config[CONF_HUMIDITY][CONF_NAME], |                                   config[CONF_HUMIDITY][CONF_NAME], | ||||||
|                                   config.get(CONF_UPDATE_INTERVAL)) |                                   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_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]) |     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], |     rhs = App.make_htu21d_sensor(config[CONF_TEMPERATURE][CONF_NAME], | ||||||
|                                  config[CONF_HUMIDITY][CONF_NAME], |                                  config[CONF_HUMIDITY][CONF_NAME], | ||||||
|                                  config.get(CONF_UPDATE_INTERVAL)) |                                  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_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]) |     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): | 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)) |                                         config.get(CONF_UPDATE_INTERVAL)) | ||||||
|     make = variable('Application::MakePulseCounter', config[CONF_ID], rhs) |     make = variable('Application::MakePulseCounterSensor', config[CONF_ID], rhs) | ||||||
|     pcnt = make.Ppcnt |     pcnt = make.Ppcnt | ||||||
|     if CONF_PULL_MODE in config: |     if CONF_PULL_MODE in config: | ||||||
|         pull_mode = GPIO_PULL_MODES[config[CONF_PULL_MODE]] |         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))) |         add(pcnt.set_edge_mode(RawExpression(rising_edge), RawExpression(falling_edge))) | ||||||
|     if CONF_INTERNAL_FILTER in config: |     if CONF_INTERNAL_FILTER in config: | ||||||
|         add(pcnt.set_filter(config[CONF_INTERNAL_FILTER])) |         add(pcnt.set_filter(config[CONF_INTERNAL_FILTER])) | ||||||
|  |     sensor.setup_sensor(pcnt, config) | ||||||
|     sensor.setup_mqtt_sensor_component(make.Pmqtt, 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): | def to_code(config): | ||||||
|     trigger = exp_gpio_output_pin(config[CONF_TRIGGER_PIN]) |     trigger = exp_gpio_output_pin(config[CONF_TRIGGER_PIN]) | ||||||
|     echo = exp_gpio_input_pin(config[CONF_ECHO_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)) |                                      config.get(CONF_UPDATE_INTERVAL)) | ||||||
|     make = variable('Application::MakeUltrasonicSensor', config[CONF_ID], rhs) |     make = variable('Application::MakeUltrasonicSensor', config[CONF_ID], rhs) | ||||||
|     ultrasonic = make.Pultrasonic |     ultrasonic = make.Pultrasonic | ||||||
| @@ -29,4 +29,9 @@ def to_code(config): | |||||||
|         add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT_TIME])) |         add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT_TIME])) | ||||||
|     elif CONF_TIMEOUT_METER in config: |     elif CONF_TIMEOUT_METER in config: | ||||||
|         add(ultrasonic.set_timeout_m(config[CONF_TIMEOUT_METER])) |         add(ultrasonic.set_timeout_m(config[CONF_TIMEOUT_METER])) | ||||||
|  |     sensor.setup_sensor(ultrasonic, config) | ||||||
|     sensor.setup_mqtt_sensor_component(make.Pmqtt, 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 voluptuous as vol | ||||||
|  |  | ||||||
| import esphomeyaml.config_validation as cv | 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 | from esphomeyaml.helpers import App, Pvariable, add, setup_mqtt_component | ||||||
|  |  | ||||||
| PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | 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, |     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): | def setup_mqtt_switch(obj, config): | ||||||
|     if CONF_ICON in config: |  | ||||||
|         add(obj.set_icon(config[CONF_ICON])) |  | ||||||
|     setup_mqtt_component(obj, config) |     setup_mqtt_component(obj, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def make_mqtt_switch_for(exp, config): | def setup_switch(obj, config): | ||||||
|     rhs = App.make_mqtt_switch_for(exp, config[CONF_NAME]) |     if CONF_ICON in config: | ||||||
|     mqtt_switch = Pvariable('switch_::MQTTSwitchComponent', config[CONF_ID], rhs) |         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) |     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): | def to_code(config): | ||||||
|     rhs = App.make_gpio_switch(exp_gpio_output_pin(config[CONF_PIN]), config[CONF_NAME]) |     rhs = App.make_gpio_switch(config[CONF_NAME], exp_gpio_output_pin(config[CONF_PIN])) | ||||||
|     gpio = variable('Application::GPIOSwitchStruct', config[CONF_ID], rhs) |     gpio = variable('Application::MakeGPIOSwitch', config[CONF_ID], rhs) | ||||||
|  |     switch.setup_switch(gpio.Pswitch_, config) | ||||||
|     switch.setup_mqtt_switch(gpio.Pmqtt, 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.components.ir_transmitter import IR_TRANSMITTER_COMPONENT_CLASS | ||||||
| from esphomeyaml.const import CONF_ADDRESS, CONF_COMMAND, CONF_DATA, CONF_IR_TRANSMITTER_ID, \ | 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_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.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({ | 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.Exclusive(CONF_NEC, 'code'): vol.Schema({ | ||||||
|         vol.Required(CONF_ADDRESS): cv.hex_uint16_t, |         vol.Required(CONF_ADDRESS): cv.hex_uint16_t, | ||||||
|         vol.Required(CONF_COMMAND): 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.Required(CONF_WAIT_TIME_US): cv.uint32_t, | ||||||
|     })), |     })), | ||||||
|     vol.Optional(CONF_IR_TRANSMITTER_ID): cv.variable_id, |     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 | # pylint: disable=invalid-name | ||||||
| @@ -86,4 +86,11 @@ def exp_send_data(config): | |||||||
| def to_code(config): | def to_code(config): | ||||||
|     ir = get_variable(config.get(CONF_IR_TRANSMITTER_ID), IR_TRANSMITTER_COMPONENT_CLASS) |     ir = get_variable(config.get(CONF_IR_TRANSMITTER_ID), IR_TRANSMITTER_COMPONENT_CLASS) | ||||||
|     send_data = exp_send_data(config) |     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 | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.components import switch | from esphomeyaml.components import switch | ||||||
| from esphomeyaml.const import CONF_ID, CONF_NAME | 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({ | PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ | ||||||
|     cv.GenerateID('restart_switch'): cv.register_variable_id, |     cv.GenerateID('restart_switch'): cv.register_variable_id, | ||||||
| @@ -10,5 +10,10 @@ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ | |||||||
|  |  | ||||||
| def to_code(config): | def to_code(config): | ||||||
|     rhs = App.make_restart_switch(config[CONF_NAME]) |     rhs = App.make_restart_switch(config[CONF_NAME]) | ||||||
|     mqtt = Pvariable('switch_::MQTTSwitchComponent', config[CONF_ID], rhs) |     restart = variable('Application::MakeRestartSwitch', config[CONF_ID], rhs) | ||||||
|     switch.setup_mqtt_switch(mqtt, config) |     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 voluptuous as vol | ||||||
|  |  | ||||||
| import esphomeyaml.config_validation as cv | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.const import CONF_DNS1, CONF_DNS2, CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, \ | from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_GATEWAY, \ | ||||||
|     CONF_MANUAL_IP, CONF_PASSWORD, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, CONF_WIFI |     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 | from esphomeyaml.helpers import App, MockObj, Pvariable, StructInitializer, add | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = cv.ID_SCHEMA.extend({ |  | ||||||
|     cv.GenerateID(CONF_WIFI): cv.register_variable_id, | def validate_password(value): | ||||||
|     vol.Required(CONF_SSID): cv.ssid, |     value = cv.string(value) | ||||||
|     vol.Optional(CONF_PASSWORD): cv.string, |     if not value: | ||||||
|     vol.Optional(CONF_MANUAL_IP): vol.Schema({ |         return value | ||||||
|         vol.Required(CONF_STATIC_IP): cv.ipv4, |     if len(value) < 8: | ||||||
|         vol.Required(CONF_GATEWAY): cv.ipv4, |         raise vol.Invalid(u"WPA password must be at least 8 characters long") | ||||||
|         vol.Required(CONF_SUBNET): cv.ipv4, |     if len(value) > 63: | ||||||
|         vol.Inclusive(CONF_DNS1, 'dns'): cv.ipv4, |         raise vol.Invalid(u"WPA password must be at most 63 characters long") | ||||||
|         vol.Inclusive(CONF_DNS2, 'dns'): cv.ipv4, |     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, |     vol.Optional(CONF_HOSTNAME): cv.hostname, | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  |  | ||||||
| # pylint: disable=invalid-name | # pylint: disable=invalid-name | ||||||
| IPAddress = MockObj('IPAddress') | IPAddress = MockObj('IPAddress') | ||||||
|  |  | ||||||
| @@ -30,19 +52,38 @@ def safe_ip(ip): | |||||||
|     return IPAddress(*ip.args) |     return IPAddress(*ip.args) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def manual_ip(config): | ||||||
|  |     return StructInitializer( | ||||||
|  |         'ManualIP', | ||||||
|  |         ('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))), | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
| def to_code(config): | def to_code(config): | ||||||
|     rhs = App.init_wifi(config[CONF_SSID], config.get(CONF_PASSWORD)) |     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) |     wifi = Pvariable('WiFiComponent', config[CONF_ID], rhs) | ||||||
|     if CONF_MANUAL_IP in config: |  | ||||||
|         manual_ip = config[CONF_MANUAL_IP] |     if sta and CONF_MANUAL_IP in config: | ||||||
|         exp = StructInitializer( |         add(wifi.set_sta_manual_ip(manual_ip(config[CONF_MANUAL_IP]))) | ||||||
|             'ManualIP', |  | ||||||
|             ('static_ip', safe_ip(manual_ip[CONF_STATIC_IP])), |     if ap: | ||||||
|             ('gateway', safe_ip(manual_ip[CONF_GATEWAY])), |         conf = config[CONF_AP] | ||||||
|             ('subnet', safe_ip(manual_ip[CONF_SUBNET])), |         password = config.get(CONF_PASSWORD) | ||||||
|             ('dns1', safe_ip(manual_ip.get(CONF_DNS1))), |         if password is None and CONF_CHANNEL in conf: | ||||||
|             ('dns2', safe_ip(manual_ip.get(CONF_DNS2))), |             password = u"" | ||||||
|         ) |         add(wifi.set_ap(conf[CONF_SSID], password, conf.get(CONF_CHANNEL))) | ||||||
|         add(wifi.set_manual_ip(exp)) |  | ||||||
|  |         if CONF_MANUAL_IP in conf: | ||||||
|  |             add(wifi.set_ap_manual_ip(manual_ip(conf[CONF_MANUAL_IP]))) | ||||||
|  |  | ||||||
|     if CONF_HOSTNAME in config: |     if CONF_HOSTNAME in config: | ||||||
|         add(wifi.set_hostname(config[CONF_HOSTNAME])) |         add(wifi.set_hostname(config[CONF_HOSTNAME])) | ||||||
|   | |||||||
| @@ -8,13 +8,12 @@ import voluptuous as vol | |||||||
| from voluptuous.humanize import humanize_error | from voluptuous.humanize import humanize_error | ||||||
|  |  | ||||||
| import esphomeyaml.config_validation as cv | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml import helpers, yaml_util | from esphomeyaml import core, yaml_util | ||||||
| from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_MQTT, \ | from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_NAME, \ | ||||||
|     CONF_NAME, \ |     CONF_PLATFORM, CONF_SIMPLIFY, CONF_USE_BUILD_FLAGS, CONF_WIFI, ESP_PLATFORMS, \ | ||||||
|     CONF_PLATFORM, CONF_SIMPLIFY, CONF_WIFI, ESP_PLATFORMS, ESP_PLATFORM_ESP32, \ |     ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 | ||||||
|     ESP_PLATFORM_ESP8266 |  | ||||||
| from esphomeyaml.core import ESPHomeYAMLError | 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__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| @@ -22,15 +21,15 @@ DEFAULT_LIBRARY_URI = u'esphomelib@1.2.1' | |||||||
|  |  | ||||||
| CORE_SCHEMA = vol.Schema({ | CORE_SCHEMA = vol.Schema({ | ||||||
|     vol.Required(CONF_NAME): cv.valid_name, |     vol.Required(CONF_NAME): cv.valid_name, | ||||||
|     vol.Required(CONF_PLATFORM): vol.All( |     vol.Required(CONF_PLATFORM): cv.string, | ||||||
|         vol.Upper, vol.Any(ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266)), |  | ||||||
|     vol.Required(CONF_BOARD): cv.string, |     vol.Required(CONF_BOARD): cv.string, | ||||||
|     vol.Optional(CONF_LIBRARY_URI, default=DEFAULT_LIBRARY_URI): cv.string, |     vol.Optional(CONF_LIBRARY_URI, default=DEFAULT_LIBRARY_URI): cv.string, | ||||||
|     vol.Optional(CONF_SIMPLIFY, default=True): cv.boolean, |     vol.Optional(CONF_SIMPLIFY, default=True): cv.boolean, | ||||||
|  |     vol.Optional(CONF_USE_BUILD_FLAGS, default=False): cv.boolean, | ||||||
| }) | }) | ||||||
|  |  | ||||||
| REQUIRED_COMPONENTS = [ | REQUIRED_COMPONENTS = [ | ||||||
|     CONF_ESPHOMEYAML, CONF_WIFI, CONF_MQTT |     CONF_ESPHOMEYAML, CONF_WIFI | ||||||
| ] | ] | ||||||
|  |  | ||||||
| _COMPONENT_CACHE = {} | _COMPONENT_CACHE = {} | ||||||
| @@ -66,8 +65,17 @@ def is_platform_component(component): | |||||||
|     return hasattr(component, 'PLATFORM_SCHEMA') |     return hasattr(component, 'PLATFORM_SCHEMA') | ||||||
|  |  | ||||||
|  |  | ||||||
| def validate_schema(config, schema): | def iter_components(config): | ||||||
|     return schema(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): | class Config(OrderedDict): | ||||||
| @@ -96,7 +104,7 @@ def validate_config(config): | |||||||
|         result.add_error(_format_config_error(ex, domain, config), domain, config) |         result.add_error(_format_config_error(ex, domain, config), domain, config) | ||||||
|  |  | ||||||
|     try: |     try: | ||||||
|         result[CONF_ESPHOMEYAML] = validate_schema(config[CONF_ESPHOMEYAML], CORE_SCHEMA) |         result[CONF_ESPHOMEYAML] = CORE_SCHEMA(config[CONF_ESPHOMEYAML]) | ||||||
|     except vol.Invalid as ex: |     except vol.Invalid as ex: | ||||||
|         _comp_error(ex, CONF_ESPHOMEYAML, config) |         _comp_error(ex, CONF_ESPHOMEYAML, config) | ||||||
|  |  | ||||||
| @@ -111,8 +119,8 @@ def validate_config(config): | |||||||
|             continue |             continue | ||||||
|  |  | ||||||
|         esp_platforms = getattr(component, 'ESP_PLATFORMS', ESP_PLATFORMS) |         esp_platforms = getattr(component, 'ESP_PLATFORMS', ESP_PLATFORMS) | ||||||
|         if cv.ESP_PLATFORM not in esp_platforms: |         if core.ESP_PLATFORM not in esp_platforms: | ||||||
|             result.add_error(u"Component {} doesn't support {}.".format(domain, cv.ESP_PLATFORM)) |             result.add_error(u"Component {} doesn't support {}.".format(domain, core.ESP_PLATFORM)) | ||||||
|             continue |             continue | ||||||
|  |  | ||||||
|         success = True |         success = True | ||||||
| @@ -129,7 +137,7 @@ def validate_config(config): | |||||||
|                 validated = component.CONFIG_SCHEMA(conf) |                 validated = component.CONFIG_SCHEMA(conf) | ||||||
|                 result[domain] = validated |                 result[domain] = validated | ||||||
|             except vol.Invalid as ex: |             except vol.Invalid as ex: | ||||||
|                 _comp_error(ex, domain, config) |                 _comp_error(ex, domain, conf) | ||||||
|                 continue |                 continue | ||||||
|  |  | ||||||
|         if not hasattr(component, 'PLATFORM_SCHEMA'): |         if not hasattr(component, 'PLATFORM_SCHEMA'): | ||||||
| @@ -138,7 +146,7 @@ def validate_config(config): | |||||||
|         platforms = [] |         platforms = [] | ||||||
|         for p_config in conf: |         for p_config in conf: | ||||||
|             if not isinstance(p_config, dict): |             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 |                 continue | ||||||
|             p_name = p_config.get(u'platform') |             p_name = p_config.get(u'platform') | ||||||
|             if p_name is None: |             if p_name is None: | ||||||
| @@ -149,6 +157,16 @@ def validate_config(config): | |||||||
|                 result.add_error(u"Platform not found: {}.{}") |                 result.add_error(u"Platform not found: {}.{}") | ||||||
|                 continue |                 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'): |             if hasattr(platform, u'PLATFORM_SCHEMA'): | ||||||
|                 try: |                 try: | ||||||
|                     p_validated = platform.PLATFORM_SCHEMA(p_config) |                     p_validated = platform.PLATFORM_SCHEMA(p_config) | ||||||
| @@ -160,7 +178,7 @@ def validate_config(config): | |||||||
|     return result |     return result | ||||||
|  |  | ||||||
|  |  | ||||||
| REQUIRED = ['esphomeyaml', 'wifi', 'mqtt'] | REQUIRED = ['esphomeyaml', 'wifi'] | ||||||
|  |  | ||||||
|  |  | ||||||
| def _format_config_error(ex, domain, config): | def _format_config_error(ex, domain, config): | ||||||
| @@ -186,13 +204,18 @@ def load_config(path): | |||||||
|     except OSError: |     except OSError: | ||||||
|         raise ESPHomeYAMLError(u"Could not read configuration file at {}".format(path)) |         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() |     esp_platform = esp_platform.upper() | ||||||
|     if esp_platform not in (ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266): |     if '8266' in esp_platform: | ||||||
|         raise ESPHomeYAMLError(u"Invalid ESP Platform {}".format(esp_platform)) |         esp_platform = ESP_PLATFORM_ESP8266 | ||||||
|     cv.ESP_PLATFORM = esp_platform |     if '32' in esp_platform: | ||||||
|     cv.BOARD = unicode(config.get(CONF_ESPHOMEYAML, {}).get(CONF_BOARD, u"")) |         esp_platform = ESP_PLATFORM_ESP32 | ||||||
|     helpers.SIMPLIFY = cv.boolean(config.get(CONF_SIMPLIFY, True)) |     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: |     try: | ||||||
|         result = validate_config(config) |         result = validate_config(config) | ||||||
| @@ -203,28 +226,6 @@ def load_config(path): | |||||||
|     return result |     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): | def line_info(obj, **kwargs): | ||||||
|     """Display line config source.""" |     """Display line config source.""" | ||||||
|     if hasattr(obj, '__config_file__'): |     if hasattr(obj, '__config_file__'): | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ from datetime import timedelta | |||||||
|  |  | ||||||
| import voluptuous as vol | import voluptuous as vol | ||||||
|  |  | ||||||
|  | from esphomeyaml import core | ||||||
| from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_ID, \ | from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_ID, \ | ||||||
|     CONF_NAME, CONF_PAYLOAD_AVAILABLE, \ |     CONF_NAME, CONF_PAYLOAD_AVAILABLE, \ | ||||||
|     CONF_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC, \ |     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_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)) | positive_not_null_int = vol.All(vol.Coerce(int), vol.Range(min=0, min_included=False)) | ||||||
|  |  | ||||||
| ESP_PLATFORM = '' |  | ||||||
| BOARD = '' |  | ||||||
|  |  | ||||||
| ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_' | ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_' | ||||||
|  |  | ||||||
| RESERVED_IDS = [ | RESERVED_IDS = [ | ||||||
| @@ -150,7 +148,7 @@ def only_on(platforms): | |||||||
|         platforms = [platforms] |         platforms = [platforms] | ||||||
|  |  | ||||||
|     def validator_(obj): |     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)) |             raise vol.Invalid(u"This feature is only available on {}".format(platforms)) | ||||||
|         return obj |         return obj | ||||||
|  |  | ||||||
| @@ -274,8 +272,8 @@ def ssid(value): | |||||||
|         raise vol.Invalid("SSID must be a string. Did you wrap it in quotes?") |         raise vol.Invalid("SSID must be a string. Did you wrap it in quotes?") | ||||||
|     if not value: |     if not value: | ||||||
|         raise vol.Invalid("SSID can't be empty.") |         raise vol.Invalid("SSID can't be empty.") | ||||||
|     if len(value) > 32: |     if len(value) > 31: | ||||||
|         raise vol.Invalid("SSID can't be longer than 32 characters") |         raise vol.Invalid("SSID can't be longer than 31 characters") | ||||||
|     return value |     return value | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -300,6 +298,8 @@ def publish_topic(value): | |||||||
|     value = string_strict(value) |     value = string_strict(value) | ||||||
|     if value.endswith('/'): |     if value.endswith('/'): | ||||||
|         raise vol.Invalid("Publish topic can't end with '/'") |         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 |     return value | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -334,23 +334,19 @@ def register_variable_id(value): | |||||||
|  |  | ||||||
|  |  | ||||||
| class GenerateID(vol.Optional): | class GenerateID(vol.Optional): | ||||||
|     def __init__(self, basename): |     def __init__(self, basename, key=CONF_ID): | ||||||
|         self._basename = basename |         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): |     def default_variable_id(self): | ||||||
|         return ensure_unique_string(self._basename, REGISTERED_IDS) |         return ensure_unique_string(self._basename, REGISTERED_IDS) | ||||||
|  |  | ||||||
|  |  | ||||||
| ID_SCHEMA = vol.Schema({ |  | ||||||
|     vol.Required(CONF_ID): invalid, |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| REQUIRED_ID_SCHEMA = vol.Schema({ | REQUIRED_ID_SCHEMA = vol.Schema({ | ||||||
|     vol.Required(CONF_ID): register_variable_id, |     vol.Required(CONF_ID): register_variable_id, | ||||||
| }) | }) | ||||||
|  |  | ||||||
| PLATFORM_SCHEMA = ID_SCHEMA.extend({ | PLATFORM_SCHEMA = vol.Schema({ | ||||||
|     vol.Required(CONF_PLATFORM): valid, |     vol.Required(CONF_PLATFORM): valid, | ||||||
| }) | }) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| MAJOR_VERSION = 1 | MAJOR_VERSION = 1 | ||||||
| MINOR_VERSION = 2 | MINOR_VERSION = 2 | ||||||
| PATCH_VERSION = '2' | PATCH_VERSION = '2-dev' | ||||||
| __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) | __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) | ||||||
| __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) | __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) | ||||||
|  |  | ||||||
| @@ -17,6 +17,7 @@ CONF_NAME = 'name' | |||||||
| CONF_PLATFORM = 'platform' | CONF_PLATFORM = 'platform' | ||||||
| CONF_BOARD = 'board' | CONF_BOARD = 'board' | ||||||
| CONF_SIMPLIFY = 'simplify' | CONF_SIMPLIFY = 'simplify' | ||||||
|  | CONF_USE_BUILD_FLAGS = 'use_build_flags' | ||||||
| CONF_LIBRARY_URI = 'library_uri' | CONF_LIBRARY_URI = 'library_uri' | ||||||
| CONF_LOGGER = 'logger' | CONF_LOGGER = 'logger' | ||||||
| CONF_WIFI = 'wifi' | CONF_WIFI = 'wifi' | ||||||
| @@ -32,6 +33,7 @@ CONF_BROKER = 'broker' | |||||||
| CONF_USERNAME = 'username' | CONF_USERNAME = 'username' | ||||||
| CONF_POWER_SUPPLY = 'power_supply' | CONF_POWER_SUPPLY = 'power_supply' | ||||||
| CONF_ID = 'id' | CONF_ID = 'id' | ||||||
|  | CONF_MQTT_ID = 'mqtt_id' | ||||||
| CONF_PIN = 'pin' | CONF_PIN = 'pin' | ||||||
| CONF_NUMBER = 'number' | CONF_NUMBER = 'number' | ||||||
| CONF_INVERTED = 'inverted' | CONF_INVERTED = 'inverted' | ||||||
| @@ -151,6 +153,14 @@ CONF_RATE = 'rate' | |||||||
| CONF_ADS1115_ID = 'ads1115_id' | CONF_ADS1115_ID = 'ads1115_id' | ||||||
| CONF_MULTIPLEXER = 'multiplexer' | CONF_MULTIPLEXER = 'multiplexer' | ||||||
| CONF_GAIN = 'gain' | 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 = [ | ESP32_BOARDS = [ | ||||||
|     'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', |     'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', | ||||||
|   | |||||||
| @@ -16,3 +16,9 @@ class IPAddress(object): | |||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return '.'.join(str(x) for x in self.args) |         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 | import re | ||||||
| from collections import OrderedDict, deque | from collections import OrderedDict, deque | ||||||
|  |  | ||||||
|  | from esphomeyaml import core | ||||||
| from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, \ | from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, \ | ||||||
|     CONF_INVERTED, \ |     CONF_INVERTED, \ | ||||||
|     CONF_MODE, CONF_NUMBER, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_RETAIN, \ |     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__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| SIMPLIFY = False |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def ensure_unique_string(preferred_string, current_strings): | def ensure_unique_string(preferred_string, current_strings): | ||||||
|     test_string = preferred_string |     test_string = preferred_string | ||||||
| @@ -45,11 +44,19 @@ def indent(text, padding=u'  '): | |||||||
|  |  | ||||||
| class Expression(object): | class Expression(object): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         pass |         self.requires = [] | ||||||
|  |         self.required = False | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         raise NotImplementedError |         raise NotImplementedError | ||||||
|  |  | ||||||
|  |     def require(self): | ||||||
|  |         self.required = True | ||||||
|  |         for require in self.requires: | ||||||
|  |             if require.required: | ||||||
|  |                 continue | ||||||
|  |             require.require() | ||||||
|  |  | ||||||
|  |  | ||||||
| class RawExpression(Expression): | class RawExpression(Expression): | ||||||
|     def __init__(self, text): |     def __init__(self, text): | ||||||
| @@ -60,15 +67,22 @@ class RawExpression(Expression): | |||||||
|         return self.text |         return self.text | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # pylint: disable=redefined-builtin | ||||||
| class AssignmentExpression(Expression): | class AssignmentExpression(Expression): | ||||||
|     def __init__(self, lhs, rhs, obj): |     def __init__(self, type, modifier, name, rhs, obj): | ||||||
|         super(AssignmentExpression, self).__init__() |         super(AssignmentExpression, self).__init__() | ||||||
|         self.obj = obj |         self.type = type | ||||||
|         self.lhs = safe_exp(lhs) |         self.modifier = modifier | ||||||
|  |         self.name = name | ||||||
|         self.rhs = safe_exp(rhs) |         self.rhs = safe_exp(rhs) | ||||||
|  |         self.requires.append(self.rhs) | ||||||
|  |         self.obj = obj | ||||||
|  |  | ||||||
|     def __str__(self): |     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): | class ExpressionList(Expression): | ||||||
| @@ -78,7 +92,11 @@ class ExpressionList(Expression): | |||||||
|         args = list(args) |         args = list(args) | ||||||
|         while args and args[-1] is None: |         while args and args[-1] is None: | ||||||
|             args.pop() |             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): |     def __str__(self): | ||||||
|         text = u", ".join(unicode(x) for x in self.args) |         text = u", ".join(unicode(x) for x in self.args) | ||||||
| @@ -90,6 +108,7 @@ class CallExpression(Expression): | |||||||
|         super(CallExpression, self).__init__() |         super(CallExpression, self).__init__() | ||||||
|         self.base = base |         self.base = base | ||||||
|         self.args = ExpressionList(*args) |         self.args = ExpressionList(*args) | ||||||
|  |         self.requires.append(self.args) | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return u'{}({})'.format(self.base, self.args) |         return u'{}({})'.format(self.base, self.args) | ||||||
| @@ -103,8 +122,11 @@ class StructInitializer(Expression): | |||||||
|             args = OrderedDict(args) |             args = OrderedDict(args) | ||||||
|         self.args = OrderedDict() |         self.args = OrderedDict() | ||||||
|         for key, value in args.iteritems(): |         for key, value in args.iteritems(): | ||||||
|             if value is not None: |             if value is None: | ||||||
|                 self.args[key] = safe_exp(value) |                 continue | ||||||
|  |             exp = safe_exp(value) | ||||||
|  |             self.args[key] = exp | ||||||
|  |             self.requires.append(exp) | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         cpp = u'{}{{\n'.format(self.base) |         cpp = u'{}{{\n'.format(self.base) | ||||||
| @@ -115,17 +137,27 @@ class StructInitializer(Expression): | |||||||
|  |  | ||||||
|  |  | ||||||
| class ArrayInitializer(Expression): | class ArrayInitializer(Expression): | ||||||
|     def __init__(self, *args): |     def __init__(self, *args, **kwargs): | ||||||
|         super(ArrayInitializer, self).__init__() |         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): |     def __str__(self): | ||||||
|         if not self.args: |         if not self.args: | ||||||
|             return u'{}' |             return u'{}' | ||||||
|         cpp = u'{\n' |         if self.multiline: | ||||||
|         for arg in self.args: |             cpp = u'{\n' | ||||||
|             cpp += u'  {},\n'.format(arg) |             for arg in self.args: | ||||||
|         cpp += u'}' |                 cpp += u'  {},\n'.format(arg) | ||||||
|  |             cpp += u'}' | ||||||
|  |         else: | ||||||
|  |             cpp = u'{' + u', '.join(str(arg) for arg in self.args) + u'}' | ||||||
|         return cpp |         return cpp | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -227,20 +259,22 @@ def statement(expression): | |||||||
|  |  | ||||||
| # pylint: disable=redefined-builtin, invalid-name | # pylint: disable=redefined-builtin, invalid-name | ||||||
| def variable(type, id, rhs): | def variable(type, id, rhs): | ||||||
|     lhs = RawExpression(u'{} {}'.format(type if not SIMPLIFY else u'auto', id)) |  | ||||||
|     rhs = safe_exp(rhs) |     rhs = safe_exp(rhs) | ||||||
|     obj = MockObj(id, u'.') |     obj = MockObj(id, u'.') | ||||||
|     add(AssignmentExpression(lhs, rhs, obj)) |     assignment = AssignmentExpression(type, '', id, rhs, obj) | ||||||
|  |     add(assignment) | ||||||
|     _VARIABLES[id] = obj, type |     _VARIABLES[id] = obj, type | ||||||
|  |     obj.requires.append(assignment) | ||||||
|     return obj |     return obj | ||||||
|  |  | ||||||
|  |  | ||||||
| def Pvariable(type, id, rhs): | def Pvariable(type, id, rhs): | ||||||
|     lhs = RawExpression(u'{} *{}'.format(type if not SIMPLIFY else u'auto', id)) |  | ||||||
|     rhs = safe_exp(rhs) |     rhs = safe_exp(rhs) | ||||||
|     obj = MockObj(id, u'->') |     obj = MockObj(id, u'->') | ||||||
|     add(AssignmentExpression(lhs, rhs, obj)) |     assignment = AssignmentExpression(type, '*', id, rhs, obj) | ||||||
|  |     add(assignment) | ||||||
|     _VARIABLES[id] = obj, type |     _VARIABLES[id] = obj, type | ||||||
|  |     obj.requires.append(assignment) | ||||||
|     return obj |     return obj | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -272,7 +306,6 @@ def get_variable(id, type=None): | |||||||
|  |  | ||||||
|         if result is None: |         if result is None: | ||||||
|             raise ESPHomeYAMLError(u"Couldn't find ID '{}' with type {}".format(id, type)) |             raise ESPHomeYAMLError(u"Couldn't find ID '{}' with type {}".format(id, type)) | ||||||
|     result.usages += 1 |  | ||||||
|     return result |     return result | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -280,17 +313,17 @@ def add_task(func, config): | |||||||
|     _QUEUE.append((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) |     _EXPRESSIONS.append(expression) | ||||||
|     return expression |     return expression | ||||||
|  |  | ||||||
|  |  | ||||||
| class MockObj(Expression): | class MockObj(Expression): | ||||||
|     def __init__(self, base, op=u'.', parent=None): |     def __init__(self, base, op=u'.'): | ||||||
|         self.base = base |         self.base = base | ||||||
|         self.op = op |         self.op = op | ||||||
|         self.usages = 0 |  | ||||||
|         self.parent = parent |  | ||||||
|         super(MockObj, self).__init__() |         super(MockObj, self).__init__() | ||||||
|  |  | ||||||
|     def __getattr__(self, attr): |     def __getattr__(self, attr): | ||||||
| @@ -299,18 +332,26 @@ class MockObj(Expression): | |||||||
|             attr = attr[1:] |             attr = attr[1:] | ||||||
|             next_op = u'->' |             next_op = u'->' | ||||||
|         op = self.op |         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): |     def __call__(self, *args, **kwargs): | ||||||
|         self.usages += 1 |         call = CallExpression(self.base, *args) | ||||||
|         it = self.parent |         obj = MockObj(call, self.op) | ||||||
|         while it is not None: |         obj.requires.append(self) | ||||||
|             it.usages += 1 |         obj.requires.append(call) | ||||||
|             it = it.parent |         return obj | ||||||
|         return CallExpression(self.base, *args) |  | ||||||
|  |  | ||||||
|     def __str__(self): |     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') | App = MockObj(u'App') | ||||||
| @@ -358,13 +399,8 @@ def setup_mqtt_component(obj, config): | |||||||
|         add(obj.set_custom_command_topic(config[CONF_COMMAND_TOPIC])) |         add(obj.set_custom_command_topic(config[CONF_COMMAND_TOPIC])) | ||||||
|     if CONF_AVAILABILITY in config: |     if CONF_AVAILABILITY in config: | ||||||
|         availability = config[CONF_AVAILABILITY] |         availability = config[CONF_AVAILABILITY] | ||||||
|         exp = StructInitializer( |         add(obj.set_availability(availability[CONF_TOPIC], availability[CONF_PAYLOAD_AVAILABLE], | ||||||
|             u'mqtt::Availability', |                                  availability[CONF_PAYLOAD_NOT_AVAILABLE])) | ||||||
|             (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)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def exp_empty_optional(type): | def exp_empty_optional(type): | ||||||
|   | |||||||
| @@ -1,13 +1,17 @@ | |||||||
| from __future__ import print_function | from __future__ import print_function | ||||||
|  |  | ||||||
|  | import hashlib | ||||||
| import logging | import logging | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
|  |  | ||||||
| import paho.mqtt.client as mqtt | import paho.mqtt.client as mqtt | ||||||
|  |  | ||||||
| from esphomeyaml.const import CONF_BROKER, CONF_DISCOVERY_PREFIX, CONF_ESPHOMEYAML, CONF_LOGGER, \ | from esphomeyaml import core | ||||||
|     CONF_LOG_TOPIC, CONF_MQTT, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_TOPIC_PREFIX, \ | 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 |     CONF_USERNAME | ||||||
|  | from esphomeyaml.helpers import color | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _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): | def show_logs(config, topic=None, username=None, password=None, client_id=None): | ||||||
|     if topic is not None: |     if topic is not None: | ||||||
|         pass  # already have topic |         pass  # already have topic | ||||||
|     elif CONF_LOG_TOPIC in config.get(CONF_LOGGER, {}): |     elif CONF_MQTT in config: | ||||||
|         topic = config[CONF_LOGGER][CONF_LOG_TOPIC] |         conf = config[CONF_MQTT] | ||||||
|     elif CONF_TOPIC_PREFIX in config[CONF_MQTT]: |         if CONF_LOG_TOPIC in conf: | ||||||
|         topic = config[CONF_MQTT][CONF_TOPIC_PREFIX] + u'/debug' |             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: |     else: | ||||||
|         topic = config[CONF_ESPHOMEYAML][CONF_NAME] + u'/debug' |         _LOGGER.error(u"MQTT isn't setup, can't start MQTT logs") | ||||||
|  |         return 1 | ||||||
|     _LOGGER.info(u"Starting log output from %s", topic) |     _LOGGER.info(u"Starting log output from %s", topic) | ||||||
|  |  | ||||||
|     def on_message(client, userdata, msg): |     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) |         print(time + msg.payload) | ||||||
|  |  | ||||||
|     return initialize(config, [topic], on_message, username, password, client_id) |     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) |         client.publish(msg.topic, None, retain=True) | ||||||
|  |  | ||||||
|     return initialize(config, [topic], on_message, username, password, client_id) |     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 voluptuous as vol | ||||||
|  |  | ||||||
| import esphomeyaml.config_validation as cv | import esphomeyaml.config_validation as cv | ||||||
|  | from esphomeyaml import core | ||||||
| from esphomeyaml.const import ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_NUMBER, CONF_MODE, \ | from esphomeyaml.const import ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_NUMBER, CONF_MODE, \ | ||||||
|     CONF_INVERTED |     CONF_INVERTED | ||||||
|  |  | ||||||
| @@ -72,32 +73,32 @@ def _translate_pin(value): | |||||||
|         pass |         pass | ||||||
|     if value.startswith('GPIO'): |     if value.startswith('GPIO'): | ||||||
|         return vol.Coerce(int)(value[len('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: |         if value in ESP32_PINS: | ||||||
|             return ESP32_PINS[value] |             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 " |             raise vol.Invalid(u"ESP32: Unknown board {} with unknown " | ||||||
|                               u"pin {}.".format(cv.BOARD, value)) |                               u"pin {}.".format(core.BOARD, value)) | ||||||
|         if value not in ESP32_BOARD_TO_PINS[cv.BOARD]: |         if value not in ESP32_BOARD_TO_PINS[core.BOARD]: | ||||||
|             raise vol.Invalid(u"ESP32: Board {} doesn't have" |             raise vol.Invalid(u"ESP32: Board {} doesn't have" | ||||||
|                               u"pin {}".format(cv.BOARD, value)) |                               u"pin {}".format(core.BOARD, value)) | ||||||
|         return ESP32_BOARD_TO_PINS[cv.BOARD][value] |         return ESP32_BOARD_TO_PINS[core.BOARD][value] | ||||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: |     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||||
|         if value in ESP8266_PINS: |         if value in ESP8266_PINS: | ||||||
|             return ESP8266_PINS[value] |             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 " |             raise vol.Invalid(u"ESP8266: Unknown board {} with unknown " | ||||||
|                               u"pin {}.".format(cv.BOARD, value)) |                               u"pin {}.".format(core.BOARD, value)) | ||||||
|         if value not in ESP8266_BOARD_TO_PINS[cv.BOARD]: |         if value not in ESP8266_BOARD_TO_PINS[core.BOARD]: | ||||||
|             raise vol.Invalid(u"ESP8266: Board {} doesn't have" |             raise vol.Invalid(u"ESP8266: Board {} doesn't have" | ||||||
|                               u"pin {}".format(cv.BOARD, value)) |                               u"pin {}".format(core.BOARD, value)) | ||||||
|         return ESP8266_BOARD_TO_PINS[cv.BOARD][value] |         return ESP8266_BOARD_TO_PINS[core.BOARD][value] | ||||||
|     raise vol.Invalid(u"Invalid ESP platform.") |     raise vol.Invalid(u"Invalid ESP platform.") | ||||||
|  |  | ||||||
|  |  | ||||||
| def _validate_gpio_pin(value): | def _validate_gpio_pin(value): | ||||||
|     value = _translate_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: |         if value < 0 or value > 39: | ||||||
|             raise vol.Invalid(u"ESP32: Invalid pin number: {}".format(value)) |             raise vol.Invalid(u"ESP32: Invalid pin number: {}".format(value)) | ||||||
|         if 6 <= value <= 11: |         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. " |             _LOGGER.warning(u"ESP32: Pin %s (20, 24, 28-31) can usually not be used. " | ||||||
|                             u"Be warned.", value) |                             u"Be warned.", value) | ||||||
|         return value |         return value | ||||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: |     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||||
|         if 6 <= value <= 11: |         if 6 <= value <= 11: | ||||||
|             _LOGGER.warning(u"ESP8266: Pin %s (6-11) might already be used by the " |             _LOGGER.warning(u"ESP8266: Pin %s (6-11) might already be used by the " | ||||||
|                             u"flash interface. Be warned.", value) |                             u"flash interface. Be warned.", value) | ||||||
| @@ -119,21 +120,21 @@ def _validate_gpio_pin(value): | |||||||
|  |  | ||||||
| def input_pin(value): | def input_pin(value): | ||||||
|     value = _validate_gpio_pin(value) |     value = _validate_gpio_pin(value) | ||||||
|     if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32: |     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||||
|         return value |         return value | ||||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: |     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||||
|         return value |         return value | ||||||
|     raise vol.Invalid(u"Invalid ESP platform.") |     raise vol.Invalid(u"Invalid ESP platform.") | ||||||
|  |  | ||||||
|  |  | ||||||
| def output_pin(value): | def output_pin(value): | ||||||
|     value = _validate_gpio_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: |         if 34 <= value <= 39: | ||||||
|             raise vol.Invalid(u"ESP32: Pin {} (34-39) can only be used as " |             raise vol.Invalid(u"ESP32: Pin {} (34-39) can only be used as " | ||||||
|                               u"input pins.".format(value)) |                               u"input pins.".format(value)) | ||||||
|         return value |         return value | ||||||
|     elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266: |     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||||
|         if value == 16: |         if value == 16: | ||||||
|             raise vol.Invalid(u"Pin {} doesn't support output mode".format(value)) |             raise vol.Invalid(u"Pin {} doesn't support output mode".format(value)) | ||||||
|         return value |         return value | ||||||
| @@ -142,11 +143,11 @@ def output_pin(value): | |||||||
|  |  | ||||||
| def analog_pin(value): | def analog_pin(value): | ||||||
|     value = _validate_gpio_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 |         if 32 <= value <= 39:  # ADC1 | ||||||
|             return value |             return value | ||||||
|         raise vol.Invalid(u"ESP32: Only pins 32 though 39 support ADC.") |         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 |         if value == 17:  # A0 | ||||||
|             return value |             return value | ||||||
|         raise vol.Invalid(u"ESP8266: Only pin A0 (17) supports ADC.") |         raise vol.Invalid(u"ESP8266: Only pin A0 (17) supports ADC.") | ||||||
| @@ -171,9 +172,9 @@ PIN_MODES_ESP32 = [ | |||||||
|  |  | ||||||
| def pin_mode(value): | def pin_mode(value): | ||||||
|     value = vol.All(vol.Coerce(str), vol.Upper)(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) |         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) |         return vol.Any(*PIN_MODES_ESP8266)(value) | ||||||
|     raise vol.Invalid(u"Invalid ESP platform.") |     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_MODE): pin_mode, | ||||||
|     vol.Optional(CONF_INVERTED): cv.boolean, |     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 errno | ||||||
| import os | import os | ||||||
|  |  | ||||||
| from esphomeyaml.config import get_component | from esphomeyaml.config import iter_components | ||||||
| from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_LOGGER, \ | from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_NAME, \ | ||||||
|     CONF_NAME, CONF_PLATFORM, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 |     CONF_PLATFORM, CONF_USE_BUILD_FLAGS, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 | ||||||
| from esphomeyaml.core import ESPHomeYAMLError | from esphomeyaml.core import ESPHomeYAMLError | ||||||
|  |  | ||||||
| CPP_AUTO_GENERATE_BEGIN = u'// ========== AUTO GENERATED CODE BEGIN ===========' | CPP_AUTO_GENERATE_BEGIN = u'// ========== AUTO GENERATED CODE BEGIN ===========' | ||||||
| @@ -52,7 +52,8 @@ framework = arduino | |||||||
| lib_deps = | lib_deps = | ||||||
|     {esphomeyaml_uri} |     {esphomeyaml_uri} | ||||||
|     ${{common.lib_deps}} |     ${{common.lib_deps}} | ||||||
| build_flags ={build_flags} | build_flags = | ||||||
|  |     {build_flags} | ||||||
|     ${{common.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): | def get_ini_content(config): | ||||||
|  |     platform = config[CONF_ESPHOMEYAML][CONF_PLATFORM] | ||||||
|  |     if platform in PLATFORM_TO_PLATFORMIO: | ||||||
|  |         platform = PLATFORM_TO_PLATFORMIO[platform] | ||||||
|     options = { |     options = { | ||||||
|         u'env': config[CONF_ESPHOMEYAML][CONF_NAME], |         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'board': config[CONF_ESPHOMEYAML][CONF_BOARD], | ||||||
|         u'esphomeyaml_uri': config[CONF_ESPHOMEYAML][CONF_LIBRARY_URI], |         u'esphomeyaml_uri': config[CONF_ESPHOMEYAML][CONF_LIBRARY_URI], | ||||||
|         u'build_flags': u'', |         u'build_flags': u'', | ||||||
|     } |     } | ||||||
|     if CONF_LOGGER in config: |     build_flags = set() | ||||||
|         build_flags = get_component(CONF_LOGGER).get_build_flags(config[CONF_LOGGER]) |     if config[CONF_ESPHOMEYAML][CONF_USE_BUILD_FLAGS]: | ||||||
|         if build_flags: |         build_flags |= get_build_flags(config, 'build_flags') | ||||||
|             options[u'build_flags'] = u'\n    ' + 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    '.join(build_flags) | ||||||
|     return INI_CONTENT_FORMAT.format(**options) |     return INI_CONTENT_FORMAT.format(**options) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -120,7 +144,7 @@ def write_platformio_ini(content, path): | |||||||
|         mkdir_p(os.path.dirname(path)) |         mkdir_p(os.path.dirname(path)) | ||||||
|         content_format = INI_BASE_FORMAT |         content_format = INI_BASE_FORMAT | ||||||
|     full_file = content_format[0] + INI_AUTO_GENERATE_BEGIN + '\n' + \ |     full_file = content_format[0] + INI_AUTO_GENERATE_BEGIN + '\n' + \ | ||||||
|         content + INI_AUTO_GENERATE_END + content_format[1] |                 content + INI_AUTO_GENERATE_END + content_format[1] | ||||||
|     if prev_file == full_file: |     if prev_file == full_file: | ||||||
|         return |         return | ||||||
|     with codecs.open(path, mode='w+', encoding='utf-8') as f_handle: |     with codecs.open(path, mode='w+', encoding='utf-8') as f_handle: | ||||||
| @@ -142,7 +166,7 @@ def write_cpp(code_s, path): | |||||||
|         code_format = CPP_BASE_FORMAT |         code_format = CPP_BASE_FORMAT | ||||||
|  |  | ||||||
|     full_file = code_format[0] + CPP_AUTO_GENERATE_BEGIN + '\n' + \ |     full_file = code_format[0] + CPP_AUTO_GENERATE_BEGIN + '\n' + \ | ||||||
|         code_s + CPP_AUTO_GENERATE_END + code_format[1] |                 code_s + CPP_AUTO_GENERATE_END + code_format[1] | ||||||
|     if prev_file == full_file: |     if prev_file == full_file: | ||||||
|         return |         return | ||||||
|     with codecs.open(path, 'w+', encoding='utf-8') as f_handle: |     with codecs.open(path, 'w+', encoding='utf-8') as f_handle: | ||||||
|   | |||||||
| @@ -1,9 +1,10 @@ | |||||||
| from __future__ import print_function | from __future__ import print_function | ||||||
|  |  | ||||||
| import codecs | import codecs | ||||||
| import fnmatch | import fnmatch | ||||||
| import logging | import logging | ||||||
| from collections import OrderedDict |  | ||||||
| import os | import os | ||||||
|  | from collections import OrderedDict | ||||||
|  |  | ||||||
| import yaml | import yaml | ||||||
|  |  | ||||||
| @@ -79,9 +80,8 @@ def _ordered_dict(loader, node): | |||||||
|  |  | ||||||
|         if key in seen: |         if key in seen: | ||||||
|             fname = getattr(loader.stream, 'name', '') |             fname = getattr(loader.stream, 'name', '') | ||||||
|             _LOGGER.error( |             raise ESPHomeYAMLError(u'YAML file {} contains duplicate key "{}". ' | ||||||
|                 u'YAML file %s contains duplicate key "%s". ' |                                    u'Check lines {} and {}.'.format(fname, key, seen[key], line)) | ||||||
|                 u'Check lines %d and %d.', fname, key, seen[key], line) |  | ||||||
|         seen[key] = line |         seen[key] = line | ||||||
|  |  | ||||||
|     return _add_reference(OrderedDict(nodes), loader, node) |     return _add_reference(OrderedDict(nodes), loader, node) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user