mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 23:21:54 +00:00 
			
		
		
		
	Update for 1.4.0
This commit is contained in:
		| @@ -139,7 +139,7 @@ def write_cpp(config): | |||||||
|     ini_path = os.path.join(get_base_path(config), 'platformio.ini') |     ini_path = os.path.join(get_base_path(config), 'platformio.ini') | ||||||
|     writer.write_platformio_ini(platformio_ini_s, ini_path) |     writer.write_platformio_ini(platformio_ini_s, ini_path) | ||||||
|  |  | ||||||
|     code_s = indent('\n'.join(all_code)) |     code_s = indent('\n'.join(line.rstrip() for line in all_code)) | ||||||
|     cpp_path = os.path.join(get_base_path(config), 'src', 'main.cpp') |     cpp_path = os.path.join(get_base_path(config), 'src', 'main.cpp') | ||||||
|     writer.write_cpp(code_s, cpp_path) |     writer.write_cpp(code_s, cpp_path) | ||||||
|     return 0 |     return 0 | ||||||
|   | |||||||
| @@ -37,5 +37,4 @@ def to_code(config): | |||||||
|             add(ads1115.set_rate(RawExpression(RATES[conf[CONF_RATE]]))) |             add(ads1115.set_rate(RawExpression(RATES[conf[CONF_RATE]]))) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_ADS1115_SENSOR' | ||||||
|     return '-DUSE_ADS1115_SENSOR' |  | ||||||
|   | |||||||
| @@ -35,5 +35,4 @@ def setup_mqtt_binary_sensor(obj, config): | |||||||
|     setup_mqtt_component(obj, config) |     setup_mqtt_component(obj, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_BINARY_SENSOR' | ||||||
|     return '-DUSE_BINARY_SENSOR' |  | ||||||
|   | |||||||
| @@ -21,5 +21,4 @@ def to_code(config): | |||||||
|     binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config) |     binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_GPIO_BINARY_SENSOR' | ||||||
|     return '-DUSE_GPIO_BINARY_SENSOR' |  | ||||||
|   | |||||||
| @@ -17,5 +17,4 @@ def to_code(config): | |||||||
|     binary_sensor.setup_mqtt_binary_sensor(status.Pmqtt, config) |     binary_sensor.setup_mqtt_binary_sensor(status.Pmqtt, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_STATUS_BINARY_SENSOR' | ||||||
|     return '-DUSE_STATUS_BINARY_SENSOR' |  | ||||||
|   | |||||||
| @@ -20,5 +20,4 @@ def to_code(config): | |||||||
|         Pvariable(DALLAS_COMPONENT_CLASS, conf[CONF_ID], rhs) |         Pvariable(DALLAS_COMPONENT_CLASS, conf[CONF_ID], rhs) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_DALLAS_SENSOR' | ||||||
|     return '-DUSE_DALLAS_SENSOR' |  | ||||||
|   | |||||||
| @@ -11,5 +11,4 @@ def to_code(config): | |||||||
|     add(App.make_debug_component()) |     add(App.make_debug_component()) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_DEBUG_COMPONENT' | ||||||
|     return '-DUSE_DEBUG_COMPONENT' |  | ||||||
|   | |||||||
| @@ -38,5 +38,4 @@ def to_code(config): | |||||||
|         add(deep_sleep.set_run_duration(config[CONF_RUN_DURATION])) |         add(deep_sleep.set_run_duration(config[CONF_RUN_DURATION])) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_DEEP_SLEEP' | ||||||
|     return '-DUSE_DEEP_SLEEP' |  | ||||||
|   | |||||||
| @@ -23,5 +23,4 @@ def setup_mqtt_fan(obj, config): | |||||||
|     setup_mqtt_component(obj, config) |     setup_mqtt_component(obj, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_FAN' | ||||||
|     return '-DUSE_FAN' |  | ||||||
|   | |||||||
| @@ -2,19 +2,23 @@ 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.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA | from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CONF_ID | ||||||
| from esphomeyaml.helpers import App, add | from esphomeyaml.helpers import App, add, Pvariable | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = vol.Schema({ | CONFIG_SCHEMA = vol.Schema({ | ||||||
|  |     cv.GenerateID('i2c'): cv.register_variable_id, | ||||||
|     vol.Required(CONF_SDA, default='SDA'): pins.input_output_pin, |     vol.Required(CONF_SDA, default='SDA'): pins.input_output_pin, | ||||||
|     vol.Required(CONF_SCL, default='SCL'): pins.input_output_pin, |     vol.Required(CONF_SCL, default='SCL'): pins.input_output_pin, | ||||||
|     vol.Optional(CONF_FREQUENCY): vol.All(cv.only_on_esp32, cv.positive_int), |     vol.Optional(CONF_FREQUENCY): vol.All(cv.only_on_esp32, cv.positive_int), | ||||||
|  |     vol.Optional(CONF_SCAN): cv.boolean, | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  |  | ||||||
| def to_code(config): | def to_code(config): | ||||||
|     add(App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_FREQUENCY))) |     rhs = App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_SCAN)) | ||||||
|  |     i2c = Pvariable('I2CComponent', config[CONF_ID], rhs) | ||||||
|  |     if CONF_FREQUENCY in config: | ||||||
|  |         add(i2c.set_frequency(config[CONF_FREQUENCY])) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_I2C' | ||||||
|     return '-DUSE_I2C' |  | ||||||
|   | |||||||
| @@ -23,5 +23,4 @@ def to_code(config): | |||||||
|         Pvariable(IR_TRANSMITTER_COMPONENT_CLASS, conf[CONF_ID], rhs) |         Pvariable(IR_TRANSMITTER_COMPONENT_CLASS, conf[CONF_ID], rhs) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_IR_TRANSMITTER' | ||||||
|     return '-DUSE_IR_TRANSMITTER' |  | ||||||
|   | |||||||
| @@ -12,5 +12,4 @@ def setup_light_component(obj, config): | |||||||
|         add(obj.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH])) |         add(obj.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH])) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_LIGHT' | ||||||
|     return '-DUSE_LIGHT' |  | ||||||
|   | |||||||
| @@ -6,15 +6,26 @@ import esphomeyaml.config_validation as cv | |||||||
| from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, CONF_DISCOVERY, \ | from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, CONF_DISCOVERY, \ | ||||||
|     CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_SSL_FINGERPRINTS, CONF_ID, CONF_LOG_TOPIC, \ |     CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_SSL_FINGERPRINTS, CONF_ID, CONF_LOG_TOPIC, \ | ||||||
|     CONF_MQTT, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, CONF_TOPIC, \ |     CONF_MQTT, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, CONF_TOPIC, \ | ||||||
|     CONF_TOPIC_PREFIX, CONF_USERNAME, CONF_WILL_MESSAGE |     CONF_TOPIC_PREFIX, CONF_USERNAME, CONF_WILL_MESSAGE, CONF_KEEPALIVE | ||||||
| from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, StructInitializer, add, \ | from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, StructInitializer, add, \ | ||||||
|     exp_empty_optional, RawExpression |     exp_empty_optional, RawExpression | ||||||
|  |  | ||||||
| MQTT_WILL_BIRTH_SCHEMA = vol.Any(None, vol.Schema({ |  | ||||||
|  | def validate_message_just_topic(value): | ||||||
|  |     value = cv.publish_topic(value) | ||||||
|  |     return {CONF_TOPIC: value} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | MQTT_MESSAGE_BASE = vol.Schema({ | ||||||
|     vol.Required(CONF_TOPIC): cv.publish_topic, |     vol.Required(CONF_TOPIC): cv.publish_topic, | ||||||
|     vol.Required(CONF_PAYLOAD): cv.mqtt_payload, |  | ||||||
|     vol.Optional(CONF_QOS, default=0): vol.All(vol.Coerce(int), vol.In([0, 1, 2])), |     vol.Optional(CONF_QOS, default=0): vol.All(vol.Coerce(int), vol.In([0, 1, 2])), | ||||||
|     vol.Optional(CONF_RETAIN, default=True): cv.boolean, |     vol.Optional(CONF_RETAIN, default=True): cv.boolean, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | MQTT_MESSAGE_TEMPLATE_SCHEMA = vol.Any(None, MQTT_MESSAGE_BASE, validate_message_just_topic) | ||||||
|  |  | ||||||
|  | MQTT_MESSAGE_SCHEMA = vol.Any(None, MQTT_MESSAGE_BASE.extend({ | ||||||
|  |     vol.Required(CONF_PAYLOAD): cv.mqtt_payload, | ||||||
| })) | })) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -47,12 +58,13 @@ CONFIG_SCHEMA = vol.Schema({ | |||||||
|     vol.Optional(CONF_DISCOVERY): cv.boolean, |     vol.Optional(CONF_DISCOVERY): cv.boolean, | ||||||
|     vol.Optional(CONF_DISCOVERY_RETAIN): cv.boolean, |     vol.Optional(CONF_DISCOVERY_RETAIN): cv.boolean, | ||||||
|     vol.Optional(CONF_DISCOVERY_PREFIX): cv.publish_topic, |     vol.Optional(CONF_DISCOVERY_PREFIX): cv.publish_topic, | ||||||
|     vol.Optional(CONF_BIRTH_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, |     vol.Optional(CONF_BIRTH_MESSAGE): MQTT_MESSAGE_SCHEMA, | ||||||
|     vol.Optional(CONF_WILL_MESSAGE): MQTT_WILL_BIRTH_SCHEMA, |     vol.Optional(CONF_WILL_MESSAGE): MQTT_MESSAGE_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_LOG_TOPIC): MQTT_MESSAGE_TEMPLATE_SCHEMA, | ||||||
|     vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266, |     vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266, | ||||||
|                                                  cv.ensure_list, [validate_fingerprint]), |                                                  cv.ensure_list, [validate_fingerprint]), | ||||||
|  |     vol.Optional(CONF_KEEPALIVE): vol.All(cv.positive_time_period, cv.time_period_to_seconds) | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -62,7 +74,7 @@ def exp_mqtt_message(config): | |||||||
|     exp = StructInitializer( |     exp = StructInitializer( | ||||||
|         'mqtt::MQTTMessage', |         'mqtt::MQTTMessage', | ||||||
|         ('topic', config[CONF_TOPIC]), |         ('topic', config[CONF_TOPIC]), | ||||||
|         ('payload', config[CONF_PAYLOAD]), |         ('payload', config.get(CONF_PAYLOAD, "")), | ||||||
|         ('qos', config[CONF_QOS]), |         ('qos', config[CONF_QOS]), | ||||||
|         ('retain', config[CONF_RETAIN]) |         ('retain', config[CONF_RETAIN]) | ||||||
|     ) |     ) | ||||||
| @@ -79,20 +91,34 @@ def to_code(config): | |||||||
|         discovery_retain = config.get(CONF_DISCOVERY_RETAIN, True) |         discovery_retain = config.get(CONF_DISCOVERY_RETAIN, True) | ||||||
|         discovery_prefix = config.get(CONF_DISCOVERY_PREFIX, 'homeassistant') |         discovery_prefix = config.get(CONF_DISCOVERY_PREFIX, 'homeassistant') | ||||||
|         add(mqtt.set_discovery_info(discovery_prefix, discovery_retain)) |         add(mqtt.set_discovery_info(discovery_prefix, discovery_retain)) | ||||||
|     if CONF_BIRTH_MESSAGE in config: |  | ||||||
|         add(mqtt.set_birth_message(config[CONF_BIRTH_MESSAGE])) |  | ||||||
|     if CONF_WILL_MESSAGE in config: |  | ||||||
|         add(mqtt.set_last_will(config[CONF_WILL_MESSAGE])) |  | ||||||
|     if CONF_TOPIC_PREFIX in config: |     if CONF_TOPIC_PREFIX in config: | ||||||
|         add(mqtt.set_topic_prefix(config[CONF_TOPIC_PREFIX])) |         add(mqtt.set_topic_prefix(config[CONF_TOPIC_PREFIX])) | ||||||
|  |     if CONF_BIRTH_MESSAGE in config: | ||||||
|  |         birth_message = config[CONF_BIRTH_MESSAGE] | ||||||
|  |         if birth_message is None: | ||||||
|  |             add(mqtt.disable_birth_message()) | ||||||
|  |         else: | ||||||
|  |             add(mqtt.set_birth_message(exp_mqtt_message(birth_message))) | ||||||
|  |     if CONF_WILL_MESSAGE in config: | ||||||
|  |         will_message = config[CONF_WILL_MESSAGE] | ||||||
|  |         if will_message is None: | ||||||
|  |             add(mqtt.disable_last_will()) | ||||||
|  |         else: | ||||||
|  |             add(mqtt.set_last_will(exp_mqtt_message(will_message))) | ||||||
|     if CONF_CLIENT_ID in config: |     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: |     if CONF_LOG_TOPIC in config: | ||||||
|         add(mqtt.set_log_topic(config[CONF_LOG_TOPIC])) |         log_topic = config[CONF_LOG_TOPIC] | ||||||
|  |         if log_topic is None: | ||||||
|  |             add(mqtt.disable_log_message()) | ||||||
|  |         else: | ||||||
|  |             add(mqtt.set_log_topic(exp_mqtt_message(log_topic))) | ||||||
|     if CONF_SSL_FINGERPRINTS in config: |     if CONF_SSL_FINGERPRINTS in config: | ||||||
|         for fingerprint in config[CONF_SSL_FINGERPRINTS]: |         for fingerprint in config[CONF_SSL_FINGERPRINTS]: | ||||||
|             arr = [RawExpression("0x{}".format(fingerprint[i:i + 2])) for i in range(0, 40, 2)] |             arr = [RawExpression("0x{}".format(fingerprint[i:i + 2])) for i in range(0, 40, 2)] | ||||||
|             add(mqtt.add_ssl_fingerprint(ArrayInitializer(*arr, multiline=False))) |             add(mqtt.add_ssl_fingerprint(ArrayInitializer(*arr, multiline=False))) | ||||||
|  |     if CONF_KEEPALIVE in config: | ||||||
|  |         add(mqtt.set_keep_alive(config[CONF_KEEPALIVE])) | ||||||
|  |  | ||||||
|  |  | ||||||
| def required_build_flags(config): | def required_build_flags(config): | ||||||
|   | |||||||
| @@ -45,5 +45,4 @@ def get_auth(config): | |||||||
|     return config[CONF_OTA].get(CONF_PASSWORD, '') |     return config[CONF_OTA].get(CONF_PASSWORD, '') | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_OTA' | ||||||
|     return '-DUSE_OTA' |  | ||||||
|   | |||||||
| @@ -25,5 +25,4 @@ def setup_output_platform(obj, config, skip_power_supply=False): | |||||||
|         add(obj.set_max_power(config[CONF_MAX_POWER])) |         add(obj.set_max_power(config[CONF_MAX_POWER])) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_OUTPUT' | ||||||
|     return '-DUSE_OUTPUT' |  | ||||||
|   | |||||||
| @@ -28,5 +28,4 @@ def to_code(config): | |||||||
|     output.setup_output_platform(gpio, config) |     output.setup_output_platform(gpio, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_ESP8266_PWM_OUTPUT' | ||||||
|     return '-DUSE_ESP8266_PWM_OUTPUT' |  | ||||||
|   | |||||||
| @@ -17,5 +17,4 @@ def to_code(config): | |||||||
|     output.setup_output_platform(gpio, config) |     output.setup_output_platform(gpio, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_GPIO_OUTPUT' | ||||||
|     return '-DUSE_GPIO_OUTPUT' |  | ||||||
|   | |||||||
| @@ -38,5 +38,4 @@ def to_code(config): | |||||||
|     output.setup_output_platform(ledc, config) |     output.setup_output_platform(ledc, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_LEDC_OUTPUT' | ||||||
|     return '-DUSE_LEDC_OUTPUT' |  | ||||||
|   | |||||||
| @@ -25,5 +25,4 @@ def to_code(config): | |||||||
|     output.setup_output_platform(out, config, skip_power_supply=True) |     output.setup_output_platform(out, config, skip_power_supply=True) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_PCA9685_OUTPUT' | ||||||
|     return '-DUSE_PCA9685_OUTPUT' |  | ||||||
|   | |||||||
| @@ -33,5 +33,4 @@ def to_code(config): | |||||||
|             add(pca9685.set_phase_balancer(phase_balancer)) |             add(pca9685.set_phase_balancer(phase_balancer)) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_PCA9685_OUTPUT' | ||||||
|     return '-DUSE_PCA9685_OUTPUT' |  | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								esphomeyaml/components/pcf8574.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								esphomeyaml/components/pcf8574.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | import voluptuous as vol | ||||||
|  |  | ||||||
|  | import esphomeyaml.config_validation as cv | ||||||
|  | from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_PCF8575 | ||||||
|  | from esphomeyaml.helpers import App, Pvariable | ||||||
|  |  | ||||||
|  | DEPENDENCIES = ['i2c'] | ||||||
|  |  | ||||||
|  | PCF8574_SCHEMA = vol.Schema({ | ||||||
|  |     vol.Required(CONF_ID): cv.register_variable_id, | ||||||
|  |     vol.Optional(CONF_ADDRESS, default=0x21): cv.i2c_address, | ||||||
|  |     vol.Optional(CONF_PCF8575, default=False): cv.boolean, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCF8574_SCHEMA]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def to_code(config): | ||||||
|  |     for conf in config: | ||||||
|  |         rhs = App.make_pcf8574_component(conf[CONF_ADDRESS], conf[CONF_PCF8575]) | ||||||
|  |         Pvariable('io::PCF8574Component', conf[CONF_ID], rhs) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | BUILD_FLAGS = '-DUSE_PCF8574' | ||||||
| @@ -25,5 +25,4 @@ def to_code(config): | |||||||
|             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): | BUILD_FLAGS = '-DUSE_OUTPUT' | ||||||
|     return '-DUSE_OUTPUT' |  | ||||||
|   | |||||||
| @@ -104,5 +104,4 @@ def register_sensor(var, config): | |||||||
|     setup_mqtt_sensor_component(mqtt_sensor, config) |     setup_mqtt_sensor_component(mqtt_sensor, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_SENSOR' | ||||||
|     return '-DUSE_SENSOR' |  | ||||||
|   | |||||||
| @@ -36,5 +36,4 @@ def to_code(config): | |||||||
|     sensor.setup_mqtt_sensor_component(make.Pmqtt, config) |     sensor.setup_mqtt_sensor_component(make.Pmqtt, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_ADC_SENSOR' | ||||||
|     return '-DUSE_ADC_SENSOR' |  | ||||||
|   | |||||||
| @@ -59,5 +59,4 @@ def to_code(config): | |||||||
|     sensor.register_sensor(sensor_, config) |     sensor.register_sensor(sensor_, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_ADS1115_SENSOR' | ||||||
|     return '-DUSE_ADS1115_SENSOR' |  | ||||||
|   | |||||||
| @@ -31,5 +31,4 @@ def to_code(config): | |||||||
|     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): | BUILD_FLAGS = '-DUSE_BMP085_SENSOR' | ||||||
|     return '-DUSE_BMP085_SENSOR' |  | ||||||
|   | |||||||
| @@ -34,5 +34,4 @@ def to_code(config): | |||||||
|     sensor.register_sensor(sensor_, config) |     sensor.register_sensor(sensor_, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_DALLAS_SENSOR' | ||||||
|     return '-DUSE_DALLAS_SENSOR' |  | ||||||
|   | |||||||
| @@ -34,5 +34,4 @@ def to_code(config): | |||||||
|     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): | BUILD_FLAGS = '-DUSE_DHT_SENSOR' | ||||||
|     return '-DUSE_DHT_SENSOR' |  | ||||||
|   | |||||||
| @@ -28,5 +28,4 @@ def to_code(config): | |||||||
|     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): | BUILD_FLAGS = '-DUSE_HDC1080_SENSOR' | ||||||
|     return '-DUSE_HDC1080_SENSOR' |  | ||||||
|   | |||||||
| @@ -28,5 +28,4 @@ def to_code(config): | |||||||
|     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): | BUILD_FLAGS = '-DUSE_HTU21D_SENSOR' | ||||||
|     return '-DUSE_HTU21D_SENSOR' |  | ||||||
|   | |||||||
							
								
								
									
										73
									
								
								esphomeyaml/components/sensor/mpu6050.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								esphomeyaml/components/sensor/mpu6050.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | import voluptuous as vol | ||||||
|  |  | ||||||
|  | import esphomeyaml.config_validation as cv | ||||||
|  | from esphomeyaml.components import sensor | ||||||
|  | from esphomeyaml.components.sensor import MQTT_SENSOR_ID_SCHEMA | ||||||
|  | from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_MQTT_ID, CONF_NAME, CONF_TEMPERATURE, \ | ||||||
|  |     CONF_UPDATE_INTERVAL | ||||||
|  | from esphomeyaml.helpers import App, Pvariable | ||||||
|  |  | ||||||
|  | DEPENDENCIES = ['i2c'] | ||||||
|  |  | ||||||
|  | CONF_ACCEL_X = 'accel_x' | ||||||
|  | CONF_ACCEL_Y = 'accel_y' | ||||||
|  | CONF_ACCEL_Z = 'accel_z' | ||||||
|  | CONF_GYRO_X = 'gyro_x' | ||||||
|  | CONF_GYRO_Y = 'gyro_y' | ||||||
|  | CONF_GYRO_Z = 'gyro_z' | ||||||
|  |  | ||||||
|  | PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ | ||||||
|  |     cv.GenerateID('mpu6050'): cv.register_variable_id, | ||||||
|  |     vol.Optional(CONF_ADDRESS, default=0x68): cv.i2c_address, | ||||||
|  |     vol.Optional(CONF_ACCEL_X): MQTT_SENSOR_ID_SCHEMA, | ||||||
|  |     vol.Optional(CONF_ACCEL_Y): MQTT_SENSOR_ID_SCHEMA, | ||||||
|  |     vol.Optional(CONF_ACCEL_Z): MQTT_SENSOR_ID_SCHEMA, | ||||||
|  |     vol.Optional(CONF_GYRO_X): MQTT_SENSOR_ID_SCHEMA, | ||||||
|  |     vol.Optional(CONF_GYRO_Y): MQTT_SENSOR_ID_SCHEMA, | ||||||
|  |     vol.Optional(CONF_GYRO_Z): MQTT_SENSOR_ID_SCHEMA, | ||||||
|  |     vol.Optional(CONF_TEMPERATURE): MQTT_SENSOR_ID_SCHEMA, | ||||||
|  |     vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def to_code(config): | ||||||
|  |     rhs = App.make_mpu6050_sensor(config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL)) | ||||||
|  |     mpu = Pvariable('sensor::MPU6050Component', config[CONF_ID], rhs) | ||||||
|  |     if CONF_ACCEL_X in config: | ||||||
|  |         conf = config[CONF_ACCEL_X] | ||||||
|  |         rhs = mpu.Pmake_accel_x_sensor(conf[CONF_NAME]) | ||||||
|  |         sensor_ = Pvariable('sensor::MPU6050AccelSensor', conf[CONF_MQTT_ID], rhs) | ||||||
|  |         sensor.register_sensor(sensor_, conf) | ||||||
|  |     if CONF_ACCEL_Y in config: | ||||||
|  |         conf = config[CONF_ACCEL_Y] | ||||||
|  |         rhs = mpu.Pmake_accel_y_sensor(conf[CONF_NAME]) | ||||||
|  |         sensor_ = Pvariable('sensor::MPU6050AccelSensor', conf[CONF_MQTT_ID], rhs) | ||||||
|  |         sensor.register_sensor(sensor_, conf) | ||||||
|  |     if CONF_ACCEL_Z in config: | ||||||
|  |         conf = config[CONF_ACCEL_Z] | ||||||
|  |         rhs = mpu.Pmake_accel_z_sensor(conf[CONF_NAME]) | ||||||
|  |         sensor_ = Pvariable('sensor::MPU6050AccelSensor', conf[CONF_MQTT_ID], rhs) | ||||||
|  |         sensor.register_sensor(sensor_, conf) | ||||||
|  |     if CONF_GYRO_X in config: | ||||||
|  |         conf = config[CONF_GYRO_X] | ||||||
|  |         rhs = mpu.Pmake_gyro_x_sensor(conf[CONF_NAME]) | ||||||
|  |         sensor_ = Pvariable('sensor::MPU6050GyroSensor', conf[CONF_MQTT_ID], rhs) | ||||||
|  |         sensor.register_sensor(sensor_, conf) | ||||||
|  |     if CONF_GYRO_Y in config: | ||||||
|  |         conf = config[CONF_GYRO_Y] | ||||||
|  |         rhs = mpu.Pmake_gyro_y_sensor(conf[CONF_NAME]) | ||||||
|  |         sensor_ = Pvariable('sensor::MPU6050GyroSensor', conf[CONF_MQTT_ID], rhs) | ||||||
|  |         sensor.register_sensor(sensor_, conf) | ||||||
|  |     if CONF_GYRO_Z in config: | ||||||
|  |         conf = config[CONF_GYRO_Z] | ||||||
|  |         rhs = mpu.Pmake_gyro_z_sensor(conf[CONF_NAME]) | ||||||
|  |         sensor_ = Pvariable('sensor::MPU6050GyroSensor', conf[CONF_MQTT_ID], rhs) | ||||||
|  |         sensor.register_sensor(sensor_, conf) | ||||||
|  |     if CONF_TEMPERATURE in config: | ||||||
|  |         conf = config[CONF_TEMPERATURE] | ||||||
|  |         rhs = mpu.Pmake_temperature_sensor(conf[CONF_NAME]) | ||||||
|  |         sensor_ = Pvariable('sensor::MPU6050TemperatureSensor', conf[CONF_MQTT_ID], rhs) | ||||||
|  |         sensor.register_sensor(sensor_, conf) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | BUILD_FLAGS = '-DUSE_MPU6050' | ||||||
| @@ -59,5 +59,4 @@ def to_code(config): | |||||||
|     sensor.setup_mqtt_sensor_component(make.Pmqtt, config) |     sensor.setup_mqtt_sensor_component(make.Pmqtt, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_PULSE_COUNTER_SENSOR' | ||||||
|     return '-DUSE_PULSE_COUNTER_SENSOR' |  | ||||||
|   | |||||||
| @@ -33,5 +33,4 @@ def to_code(config): | |||||||
|     sensor.setup_mqtt_sensor_component(make.Pmqtt, config) |     sensor.setup_mqtt_sensor_component(make.Pmqtt, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_ULTRASONIC_SENSOR' | ||||||
|     return '-DUSE_ULTRASONIC_SENSOR' |  | ||||||
|   | |||||||
| @@ -33,5 +33,4 @@ def register_switch(var, config): | |||||||
|     setup_mqtt_switch(mqtt_switch, config) |     setup_mqtt_switch(mqtt_switch, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_SWITCH' | ||||||
|     return '-DUSE_SWITCH' |  | ||||||
|   | |||||||
| @@ -19,5 +19,4 @@ def to_code(config): | |||||||
|     switch.setup_mqtt_switch(gpio.Pmqtt, config) |     switch.setup_mqtt_switch(gpio.Pmqtt, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_GPIO_SWITCH' | ||||||
|     return '-DUSE_GPIO_SWITCH' |  | ||||||
|   | |||||||
| @@ -92,5 +92,4 @@ def to_code(config): | |||||||
|     switch.register_switch(switch_, config) |     switch.register_switch(switch_, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_IR_TRANSMITTER' | ||||||
|     return '-DUSE_IR_TRANSMITTER' |  | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								esphomeyaml/components/switch/output.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								esphomeyaml/components/switch/output.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | import voluptuous as vol | ||||||
|  |  | ||||||
|  | import esphomeyaml.config_validation as cv | ||||||
|  | from esphomeyaml.components import switch | ||||||
|  | from esphomeyaml.const import CONF_ID, CONF_NAME | ||||||
|  | from esphomeyaml.helpers import App, get_variable, variable | ||||||
|  |  | ||||||
|  | PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ | ||||||
|  |     cv.GenerateID('output_switch'): cv.register_variable_id, | ||||||
|  |     vol.Required(CONF_ID): cv.variable_id, | ||||||
|  | }).extend(switch.MQTT_SWITCH_SCHEMA.schema) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def to_code(config): | ||||||
|  |     output = get_variable(config[CONF_ID]) | ||||||
|  |     rhs = App.make_simple_switch(config[CONF_NAME], output) | ||||||
|  |     gpio = variable('Application::MakeSimpleSwitch', config[CONF_ID], rhs) | ||||||
|  |     switch.setup_switch(gpio.Pswitch_, config) | ||||||
|  |     switch.setup_mqtt_switch(gpio.Pmqtt, config) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | BUILD_FLAGS = '-DUSE_SIMPLE_SWITCH' | ||||||
| @@ -15,5 +15,4 @@ def to_code(config): | |||||||
|     switch.setup_mqtt_switch(restart.Pmqtt, config) |     switch.setup_mqtt_switch(restart.Pmqtt, config) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_RESTART_SWITCH' | ||||||
|     return '-DUSE_RESTART_SWITCH' |  | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								esphomeyaml/components/switch/shutdown.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								esphomeyaml/components/switch/shutdown.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | import esphomeyaml.config_validation as cv | ||||||
|  | from esphomeyaml.components import switch | ||||||
|  | from esphomeyaml.const import CONF_ID, CONF_NAME | ||||||
|  | from esphomeyaml.helpers import App, variable | ||||||
|  |  | ||||||
|  | PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ | ||||||
|  |     cv.GenerateID('shutdown_switch'): cv.register_variable_id, | ||||||
|  | }).extend(switch.MQTT_SWITCH_SCHEMA.schema) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def to_code(config): | ||||||
|  |     rhs = App.make_shutdown_switch(config[CONF_NAME]) | ||||||
|  |     shutdown = variable('Application::MakeShutdownSwitch', config[CONF_ID], | ||||||
|  |                         rhs) | ||||||
|  |     switch.setup_switch(shutdown.Pshutdown, config) | ||||||
|  |     switch.setup_mqtt_switch(shutdown.Pmqtt, config) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | BUILD_FLAGS = '-DUSE_SHUTDOWN_SWITCH' | ||||||
| @@ -25,5 +25,4 @@ def to_code(config): | |||||||
|         add(web_server.set_js_url(config[CONF_JS_URL])) |         add(web_server.set_js_url(config[CONF_JS_URL])) | ||||||
|  |  | ||||||
|  |  | ||||||
| def build_flags(config): | BUILD_FLAGS = '-DUSE_WEB_SERVER' | ||||||
|     return '-DUSE_WEB_SERVER' |  | ||||||
|   | |||||||
| @@ -190,6 +190,9 @@ def _format_config_error(ex, domain, config): | |||||||
|     else: |     else: | ||||||
|         message += u'{}.'.format(humanize_error(config, ex)) |         message += u'{}.'.format(humanize_error(config, ex)) | ||||||
|  |  | ||||||
|  |     if isinstance(config, list): | ||||||
|  |         return message | ||||||
|  |  | ||||||
|     domain_config = config.get(domain, config) |     domain_config = config.get(domain, config) | ||||||
|     message += u" (See {}, line {}). ".format( |     message += u" (See {}, line {}). ".format( | ||||||
|         getattr(domain_config, '__config_file__', '?'), |         getattr(domain_config, '__config_file__', '?'), | ||||||
| @@ -203,6 +206,7 @@ def load_config(path): | |||||||
|         config = yaml_util.load_yaml(path) |         config = yaml_util.load_yaml(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)) | ||||||
|  |     core.RAW_CONFIG = config | ||||||
|  |  | ||||||
|     if CONF_ESPHOMEYAML not in config: |     if CONF_ESPHOMEYAML not in config: | ||||||
|         raise ESPHomeYAMLError(u"No esphomeyaml section in config") |         raise ESPHomeYAMLError(u"No esphomeyaml section in config") | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| from __future__ import print_function | from __future__ import print_function | ||||||
|  |  | ||||||
| import logging | import logging | ||||||
|  | import re | ||||||
| from datetime import timedelta | from datetime import timedelta | ||||||
|  |  | ||||||
| import voluptuous as vol | import voluptuous as vol | ||||||
| @@ -192,30 +193,65 @@ time_period_dict = vol.All( | |||||||
|     lambda value: timedelta(**value)) |     lambda value: timedelta(**value)) | ||||||
|  |  | ||||||
|  |  | ||||||
| def time_period_str(value): | def time_period_str_colon(value): | ||||||
|     """Validate and transform time offset.""" |     """Validate and transform time offset with format HH:MM[:SS].""" | ||||||
|     if isinstance(value, int): |     if isinstance(value, int): | ||||||
|         raise vol.Invalid("Make sure you wrap time values in quotes") |         raise vol.Invalid('Make sure you wrap time values in quotes') | ||||||
|     elif not isinstance(value, (str, unicode)): |     elif not isinstance(value, str): | ||||||
|         raise vol.Invalid(TIME_PERIOD_ERROR.format(value)) |         raise vol.Invalid(TIME_PERIOD_ERROR.format(value)) | ||||||
|  |  | ||||||
|     value = unicode(value) |     negative_offset = False | ||||||
|     if value.endswith(u'ms'): |     if value.startswith('-'): | ||||||
|         return vol.Coerce(int)(value[:-2]) |         negative_offset = True | ||||||
|     elif value.endswith(u's'): |         value = value[1:] | ||||||
|         return vol.Coerce(float)(value[:-1]) * 1000 |     elif value.startswith('+'): | ||||||
|     elif value.endswith(u'min'): |         value = value[1:] | ||||||
|         return vol.Coerce(float)(value[:-3]) * 1000 * 60 |  | ||||||
|     elif value.endswith(u'h'): |  | ||||||
|         return vol.Coerce(float)(value[:-1]) * 1000 * 60 * 60 |  | ||||||
|     raise vol.Invalid(TIME_PERIOD_ERROR.format(value)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def time_period_milliseconds(value): |  | ||||||
|     try: |     try: | ||||||
|         return timedelta(milliseconds=int(value)) |         parsed = [int(x) for x in value.split(':')] | ||||||
|     except (ValueError, TypeError): |     except ValueError: | ||||||
|         raise vol.Invalid('Expected milliseconds, got {}'.format(value)) |         raise vol.Invalid(TIME_PERIOD_ERROR.format(value)) | ||||||
|  |  | ||||||
|  |     if len(parsed) == 2: | ||||||
|  |         hour, minute = parsed | ||||||
|  |         second = 0 | ||||||
|  |     elif len(parsed) == 3: | ||||||
|  |         hour, minute, second = parsed | ||||||
|  |     else: | ||||||
|  |         raise vol.Invalid(TIME_PERIOD_ERROR.format(value)) | ||||||
|  |  | ||||||
|  |     offset = timedelta(hours=hour, minutes=minute, seconds=second) | ||||||
|  |  | ||||||
|  |     if negative_offset: | ||||||
|  |         offset *= -1 | ||||||
|  |  | ||||||
|  |     return offset | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def time_period_str_unit(value): | ||||||
|  |     """Validate and transform time period with time unit and integer value.""" | ||||||
|  |     if isinstance(value, int): | ||||||
|  |         value = str(value) | ||||||
|  |     elif not isinstance(value, str): | ||||||
|  |         raise vol.Invalid("Expected string for time period with unit.") | ||||||
|  |  | ||||||
|  |     unit_to_kwarg = { | ||||||
|  |         'ms': 'milliseconds', | ||||||
|  |         's': 'seconds', | ||||||
|  |         'sec': 'seconds', | ||||||
|  |         'min': 'minutes', | ||||||
|  |         'h': 'hours', | ||||||
|  |         'd': 'days', | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     match = re.match(r"^([-+]?\d+)\s*(\w*)$", value) | ||||||
|  |  | ||||||
|  |     if match is None or match.group(2) not in unit_to_kwarg: | ||||||
|  |         raise vol.Invalid(u"Expected time period with unit, " | ||||||
|  |                           u"got {}".format(value)) | ||||||
|  |  | ||||||
|  |     kwarg = unit_to_kwarg[match.group(2)] | ||||||
|  |     return timedelta(**{kwarg: int(match.group(1))}) | ||||||
|  |  | ||||||
|  |  | ||||||
| def time_period_to_milliseconds(value): | def time_period_to_milliseconds(value): | ||||||
| @@ -223,11 +259,18 @@ def time_period_to_milliseconds(value): | |||||||
|         return value |         return value | ||||||
|     if isinstance(value, float): |     if isinstance(value, float): | ||||||
|         return int(value) |         return int(value) | ||||||
|     return value / timedelta(milliseconds=1) |     return int(value.total_seconds() * 1000) | ||||||
|  |  | ||||||
|  |  | ||||||
| time_period = vol.All(vol.Any(time_period_str, timedelta, time_period_dict, | def time_period_to_seconds(value): | ||||||
|                               time_period_milliseconds), time_period_to_milliseconds) |     if value / 1000 != value // 1000: | ||||||
|  |         raise vol.Invalid("Fractions of seconds are not supported here.") | ||||||
|  |     return value / 1000 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | time_period = vol.All(vol.Any(time_period_str_colon, time_period_str_unit, timedelta, | ||||||
|  |                               time_period_dict), | ||||||
|  |                       time_period_to_milliseconds) | ||||||
| positive_time_period = vol.All(time_period, vol.Range(min=0)) | positive_time_period = vol.All(time_period, vol.Range(min=0)) | ||||||
| positive_not_null_time_period = vol.All(time_period, vol.Range(min=0, min_included=False)) | positive_not_null_time_period = vol.All(time_period, vol.Range(min=0, min_included=False)) | ||||||
|  |  | ||||||
| @@ -294,17 +337,62 @@ def ipv4(value): | |||||||
|     return IPAddress(*parts_) |     return IPAddress(*parts_) | ||||||
|  |  | ||||||
|  |  | ||||||
| def publish_topic(value): | def _valid_topic(value): | ||||||
|     value = string_strict(value) |     """Validate that this is a valid topic name/filter.""" | ||||||
|     if value.endswith('/'): |     if isinstance(value, dict): | ||||||
|         raise vol.Invalid("Publish topic can't end with '/'") |         raise vol.Invalid("Can't use dictionary with topic") | ||||||
|     if '+' in value or '#' in value: |     value = string(value) | ||||||
|         raise vol.Invalid("Publish topic can't contain '+' or '#'") |     try: | ||||||
|  |         raw_value = value.encode('utf-8') | ||||||
|  |     except UnicodeError: | ||||||
|  |         raise vol.Invalid("MQTT topic name/filter must be valid UTF-8 string.") | ||||||
|  |     if not raw_value: | ||||||
|  |         raise vol.Invalid("MQTT topic name/filter must not be empty.") | ||||||
|  |     if len(raw_value) > 65535: | ||||||
|  |         raise vol.Invalid("MQTT topic name/filter must not be longer than " | ||||||
|  |                           "65535 encoded bytes.") | ||||||
|  |     if '\0' in value: | ||||||
|  |         raise vol.Invalid("MQTT topic name/filter must not contain null " | ||||||
|  |                           "character.") | ||||||
|     return value |     return value | ||||||
|  |  | ||||||
|  |  | ||||||
| subscribe_topic = string_strict  # TODO improve this | def subscribe_topic(value): | ||||||
| mqtt_payload = string  # TODO improve this |     """Validate that we can subscribe using this MQTT topic.""" | ||||||
|  |     value = _valid_topic(value) | ||||||
|  |     for i in (i for i, c in enumerate(value) if c == '+'): | ||||||
|  |         if (i > 0 and value[i - 1] != '/') or \ | ||||||
|  |                 (i < len(value) - 1 and value[i + 1] != '/'): | ||||||
|  |             raise vol.Invalid("Single-level wildcard must occupy an entire " | ||||||
|  |                               "level of the filter") | ||||||
|  |  | ||||||
|  |     index = value.find('#') | ||||||
|  |     if index != -1: | ||||||
|  |         if index != len(value) - 1: | ||||||
|  |             # If there are multiple wildcards, this will also trigger | ||||||
|  |             raise vol.Invalid("Multi-level wildcard must be the last " | ||||||
|  |                               "character in the topic filter.") | ||||||
|  |         if len(value) > 1 and value[index - 1] != '/': | ||||||
|  |             raise vol.Invalid("Multi-level wildcard must be after a topic " | ||||||
|  |                               "level separator.") | ||||||
|  |  | ||||||
|  |     return value | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def publish_topic(value): | ||||||
|  |     """Validate that we can publish using this MQTT topic.""" | ||||||
|  |     value = _valid_topic(value) | ||||||
|  |     if '+' in value or '#' in value: | ||||||
|  |         raise vol.Invalid("Wildcards can not be used in topic names") | ||||||
|  |     return value | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def mqtt_payload(value): | ||||||
|  |     if value is None: | ||||||
|  |         return '' | ||||||
|  |     return string(value) | ||||||
|  |  | ||||||
|  |  | ||||||
| uint8_t = vol.All(int_, vol.Range(min=0, max=255)) | uint8_t = vol.All(int_, vol.Range(min=0, max=255)) | ||||||
| uint16_t = vol.All(int_, vol.Range(min=0, max=65535)) | uint16_t = vol.All(int_, vol.Range(min=0, max=65535)) | ||||||
| uint32_t = vol.All(int_, vol.Range(min=0, max=4294967295)) | uint32_t = vol.All(int_, vol.Range(min=0, max=4294967295)) | ||||||
|   | |||||||
| @@ -161,6 +161,9 @@ CONF_AP = 'ap' | |||||||
| CONF_CSS_URL = 'css_url' | CONF_CSS_URL = 'css_url' | ||||||
| CONF_JS_URL = 'js_url' | CONF_JS_URL = 'js_url' | ||||||
| CONF_SSL_FINGERPRINTS = 'ssl_fingerprints' | CONF_SSL_FINGERPRINTS = 'ssl_fingerprints' | ||||||
|  | CONF_PCF8575 = 'pcf8575' | ||||||
|  | CONF_SCAN = 'scan' | ||||||
|  | CONF_KEEPALIVE = 'keepalive' | ||||||
|  |  | ||||||
| ESP32_BOARDS = [ | ESP32_BOARDS = [ | ||||||
|     'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', |     'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', | ||||||
|   | |||||||
| @@ -22,3 +22,4 @@ CONFIG_PATH = None | |||||||
| SIMPLIFY = True | SIMPLIFY = True | ||||||
| ESP_PLATFORM = '' | ESP_PLATFORM = '' | ||||||
| BOARD = '' | BOARD = '' | ||||||
|  | RAW_CONFIG = None | ||||||
|   | |||||||
| @@ -370,6 +370,18 @@ def get_gpio_pin_number(conf): | |||||||
| def exp_gpio_pin_(obj, conf, default_mode): | def exp_gpio_pin_(obj, conf, default_mode): | ||||||
|     if isinstance(conf, int): |     if isinstance(conf, int): | ||||||
|         return conf |         return conf | ||||||
|  |  | ||||||
|  |     if 'pcf8574' in conf: | ||||||
|  |         hub = get_variable(conf['pcf8574']) | ||||||
|  |         if default_mode == u'INPUT': | ||||||
|  |             return hub.make_input_pin(conf[CONF_NUMBER], | ||||||
|  |                                       RawExpression('PCF8574_' + conf[CONF_MODE]), | ||||||
|  |                                       conf[CONF_INVERTED]) | ||||||
|  |         elif default_mode == u'OUTPUT': | ||||||
|  |             return hub.make_output_pin(conf[CONF_NUMBER], conf[CONF_INVERTED]) | ||||||
|  |         else: | ||||||
|  |             raise ESPHomeYAMLError(u"Unknown default mode {}".format(default_mode)) | ||||||
|  |  | ||||||
|     if conf.get(CONF_INVERTED) is None: |     if conf.get(CONF_INVERTED) is None: | ||||||
|         return obj(conf[CONF_NUMBER], conf.get(CONF_MODE)) |         return obj(conf[CONF_NUMBER], conf.get(CONF_MODE)) | ||||||
|     return obj(conf[CONF_NUMBER], RawExpression(conf.get(CONF_MODE, default_mode)), |     return obj(conf[CONF_NUMBER], RawExpression(conf.get(CONF_MODE, default_mode)), | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import voluptuous as vol | |||||||
| import esphomeyaml.config_validation as cv | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml import core | 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, CONF_ID, CONF_PCF8575 | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| @@ -72,7 +72,7 @@ def _translate_pin(value): | |||||||
|     except ValueError: |     except ValueError: | ||||||
|         pass |         pass | ||||||
|     if value.startswith('GPIO'): |     if value.startswith('GPIO'): | ||||||
|         return vol.Coerce(int)(value[len('GPIO'):]) |         return vol.Coerce(int)(value[len('GPIO'):].strip()) | ||||||
|     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: |     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||||
|         if value in ESP32_PINS: |         if value in ESP32_PINS: | ||||||
|             return ESP32_PINS[value] |             return ESP32_PINS[value] | ||||||
| @@ -80,7 +80,7 @@ def _translate_pin(value): | |||||||
|             raise vol.Invalid(u"ESP32: Unknown board {} with unknown " |             raise vol.Invalid(u"ESP32: Unknown board {} with unknown " | ||||||
|                               u"pin {}.".format(core.BOARD, value)) |                               u"pin {}.".format(core.BOARD, value)) | ||||||
|         if value not in ESP32_BOARD_TO_PINS[core.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(core.BOARD, value)) |                               u"pin {}".format(core.BOARD, value)) | ||||||
|         return ESP32_BOARD_TO_PINS[core.BOARD][value] |         return ESP32_BOARD_TO_PINS[core.BOARD][value] | ||||||
|     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: |     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||||
| @@ -90,7 +90,7 @@ def _translate_pin(value): | |||||||
|             raise vol.Invalid(u"ESP8266: Unknown board {} with unknown " |             raise vol.Invalid(u"ESP8266: Unknown board {} with unknown " | ||||||
|                               u"pin {}.".format(core.BOARD, value)) |                               u"pin {}.".format(core.BOARD, value)) | ||||||
|         if value not in ESP8266_BOARD_TO_PINS[core.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(core.BOARD, value)) |                               u"pin {}".format(core.BOARD, value)) | ||||||
|         return ESP8266_BOARD_TO_PINS[core.BOARD][value] |         return ESP8266_BOARD_TO_PINS[core.BOARD][value] | ||||||
|     raise vol.Invalid(u"Invalid ESP platform.") |     raise vol.Invalid(u"Invalid ESP platform.") | ||||||
| @@ -179,19 +179,57 @@ def pin_mode(value): | |||||||
|     raise vol.Invalid(u"Invalid ESP platform.") |     raise vol.Invalid(u"Invalid ESP platform.") | ||||||
|  |  | ||||||
|  |  | ||||||
| GPIO_PIN_SCHEMA = vol.Schema({ | def pcf8574_pin(value, default_mode): | ||||||
|     vol.Required(CONF_NUMBER): gpio_pin, |     if 'pcf8574' not in core.RAW_CONFIG: | ||||||
|     vol.Required(CONF_MODE): pin_mode, |         raise vol.Invalid("PCF8574 not loaded, ignore this.") | ||||||
|     vol.Optional(CONF_INVERTED): cv.boolean, |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| GPIO_OUTPUT_PIN_SCHEMA = vol.Any(output_pin, vol.Schema({ |     if isinstance(value, (str, unicode)): | ||||||
|  |         value = {CONF_NUMBER: value} | ||||||
|  |  | ||||||
|  |     if not isinstance(value, dict) or not isinstance(value.get(CONF_NUMBER), (str, unicode)) or \ | ||||||
|  |             value[CONF_NUMBER].count('.') != 1: | ||||||
|  |         raise vol.Invalid("Not PCF8574 pin") | ||||||
|  |  | ||||||
|  |     pcf_id, pin = value[CONF_NUMBER].split('.') | ||||||
|  |     pin = vol.Coerce(int)(pin) | ||||||
|  |  | ||||||
|  |     pcf_conf = cv.ensure_list(core.RAW_CONFIG['pcf8574']) | ||||||
|  |     pcf = next((conf for conf in pcf_conf if conf[CONF_ID] == pcf_id), None) | ||||||
|  |     if pcf is None: | ||||||
|  |         raise vol.Invalid("Unknown PCF8574 id: {}".format(pcf_id)) | ||||||
|  |  | ||||||
|  |     if pcf.get(CONF_PCF8575, False): | ||||||
|  |         pin = vol.Range(min=0, max=15)(pin) | ||||||
|  |     else: | ||||||
|  |         pin = vol.Range(min=0, max=7)(pin) | ||||||
|  |  | ||||||
|  |     mode = vol.All(vol.Coerce(str), vol.Upper)(value.get(CONF_MODE, default_mode)) | ||||||
|  |     if mode not in ['INPUT', 'INPUT_PULLUP', 'OUTPUT']: | ||||||
|  |         raise vol.Invalid("Invalid pin mode for PCF8575: {}".format(mode)) | ||||||
|  |  | ||||||
|  |     return { | ||||||
|  |         'pcf8574': pcf[CONF_ID], | ||||||
|  |         CONF_NUMBER: pin, | ||||||
|  |         CONF_INVERTED: value.get(CONF_INVERTED, False), | ||||||
|  |         CONF_MODE: mode | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def pcf8574_output_pin(value): | ||||||
|  |     return pcf8574_pin(value, 'OUTPUT') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def pcf8574_input_pin(value): | ||||||
|  |     return pcf8574_pin(value, 'INPUT') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | GPIO_OUTPUT_PIN_SCHEMA = vol.Any(output_pin, pcf8574_output_pin, vol.Schema({ | ||||||
|     vol.Required(CONF_NUMBER): output_pin, |     vol.Required(CONF_NUMBER): output_pin, | ||||||
|     vol.Optional(CONF_MODE): pin_mode, |     vol.Optional(CONF_MODE): pin_mode, | ||||||
|     vol.Optional(CONF_INVERTED): cv.boolean, |     vol.Optional(CONF_INVERTED): cv.boolean, | ||||||
| })) | })) | ||||||
|  |  | ||||||
| GPIO_INPUT_PIN_SCHEMA = vol.Any(input_pin, vol.Schema({ | GPIO_INPUT_PIN_SCHEMA = vol.Any(input_pin, pcf8574_input_pin, vol.Schema({ | ||||||
|     vol.Required(CONF_NUMBER): input_pin, |     vol.Required(CONF_NUMBER): input_pin, | ||||||
|     vol.Optional(CONF_MODE): pin_mode, |     vol.Optional(CONF_MODE): pin_mode, | ||||||
|     vol.Optional(CONF_INVERTED): cv.boolean, |     vol.Optional(CONF_INVERTED): cv.boolean, | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ import codecs | |||||||
| import errno | import errno | ||||||
| import os | import os | ||||||
|  |  | ||||||
|  | from esphomeyaml import core | ||||||
| from esphomeyaml.config import iter_components | from esphomeyaml.config import iter_components | ||||||
| from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_NAME, \ | from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_NAME, \ | ||||||
|     CONF_PLATFORM, CONF_USE_BUILD_FLAGS, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 |     CONF_PLATFORM, CONF_USE_BUILD_FLAGS, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 | ||||||
| @@ -50,7 +51,7 @@ platform = {platform} | |||||||
| board = {board} | board = {board} | ||||||
| framework = arduino | framework = arduino | ||||||
| lib_deps = | lib_deps = | ||||||
|     {esphomeyaml_uri} |     {lib_deps} | ||||||
|     ${{common.lib_deps}} |     ${{common.lib_deps}} | ||||||
| build_flags = | build_flags = | ||||||
|     {build_flags} |     {build_flags} | ||||||
| @@ -68,7 +69,9 @@ def get_build_flags(config, key): | |||||||
|     for _, component, conf in iter_components(config): |     for _, component, conf in iter_components(config): | ||||||
|         if not hasattr(component, key): |         if not hasattr(component, key): | ||||||
|             continue |             continue | ||||||
|         flags = getattr(component, key)(conf) |         flags = getattr(component, key) | ||||||
|  |         if callable(flags): | ||||||
|  |             flags = flags(conf) | ||||||
|         if flags is None: |         if flags is None: | ||||||
|             continue |             continue | ||||||
|         if isinstance(flags, (str, unicode)): |         if isinstance(flags, (str, unicode)): | ||||||
| @@ -85,12 +88,12 @@ def get_ini_content(config): | |||||||
|         u'env': config[CONF_ESPHOMEYAML][CONF_NAME], |         u'env': config[CONF_ESPHOMEYAML][CONF_NAME], | ||||||
|         u'platform': 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'build_flags': u'', |         u'build_flags': u'', | ||||||
|     } |     } | ||||||
|     build_flags = set() |     build_flags = set() | ||||||
|     if config[CONF_ESPHOMEYAML][CONF_USE_BUILD_FLAGS]: |     if config[CONF_ESPHOMEYAML][CONF_USE_BUILD_FLAGS]: | ||||||
|         build_flags |= get_build_flags(config, 'build_flags') |         build_flags |= get_build_flags(config, 'build_flags') | ||||||
|  |         build_flags |= get_build_flags(config, 'BUILD_FLAGS') | ||||||
|         build_flags.add(u"-DESPHOMEYAML_USE") |         build_flags.add(u"-DESPHOMEYAML_USE") | ||||||
|     build_flags |= get_build_flags(config, 'required_build_flags') |     build_flags |= get_build_flags(config, 'required_build_flags') | ||||||
|  |  | ||||||
| @@ -98,6 +101,31 @@ def get_ini_content(config): | |||||||
|     build_flags = sorted(list(build_flags)) |     build_flags = sorted(list(build_flags)) | ||||||
|     if build_flags: |     if build_flags: | ||||||
|         options[u'build_flags'] = u'\n    '.join(build_flags) |         options[u'build_flags'] = u'\n    '.join(build_flags) | ||||||
|  |  | ||||||
|  |     lib_deps = set() | ||||||
|  |     lib_deps.add(config[CONF_ESPHOMEYAML][CONF_LIBRARY_URI]) | ||||||
|  |     if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: | ||||||
|  |         lib_deps |= { | ||||||
|  |             'ArduinoOTA', | ||||||
|  |             'Update', | ||||||
|  |             'ESPmDNS', | ||||||
|  |             'Wire', | ||||||
|  |             'FS', | ||||||
|  |             'Preferences', | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |     elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: | ||||||
|  |         lib_deps |= { | ||||||
|  |             'ESP8266WiFi', | ||||||
|  |             'Wire', | ||||||
|  |             'Hash', | ||||||
|  |             'ESP8266mDNS', | ||||||
|  |             'ArduinoOTA', | ||||||
|  |         } | ||||||
|  |     else: | ||||||
|  |         raise ESPHomeYAMLError("Unsupported platform {}".format(core.ESP_PLATFORM)) | ||||||
|  |     options[u'lib_deps'] = u'\n    '.join(sorted(list(lib_deps))) | ||||||
|  |  | ||||||
|     return INI_CONTENT_FORMAT.format(**options) |     return INI_CONTENT_FORMAT.format(**options) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user