diff --git a/esphome/components/remote_receiver.py b/esphome/components/remote_receiver.py index cb49833bc3..8857baa8d3 100644 --- a/esphome/components/remote_receiver.py +++ b/esphome/components/remote_receiver.py @@ -42,7 +42,8 @@ def validate_dumpers_all(value): CONFIG_SCHEMA = cv.Schema({ cv.GenerateID(): cv.declare_variable_id(RemoteReceiverComponent), - vol.Required(CONF_PIN): pins.gpio_input_pin_schema, + vol.Required(CONF_PIN): vol.All(pins.internal_gpio_input_pin_schema, + pins.validate_has_interrupt), vol.Optional(CONF_DUMP, default=[]): vol.Any(validate_dumpers_all, cv.ensure_list(cv.one_of(*DUMPERS, lower=True))), vol.Optional(CONF_TOLERANCE): vol.All(cv.percentage_int, vol.Range(min=0)), diff --git a/esphome/components/sensor/duty_cycle.py b/esphome/components/sensor/duty_cycle.py index a083015a3f..ed3ae17bcd 100644 --- a/esphome/components/sensor/duty_cycle.py +++ b/esphome/components/sensor/duty_cycle.py @@ -12,7 +12,8 @@ DutyCycleSensor = sensor.sensor_ns.class_('DutyCycleSensor', sensor.PollingSenso PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(DutyCycleSensor), - vol.Required(CONF_PIN): pins.internal_gpio_input_pin_schema, + vol.Required(CONF_PIN): vol.All(pins.internal_gpio_input_pin_schema, + pins.validate_has_interrupt), vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval, }).extend(cv.COMPONENT_SCHEMA.schema)) diff --git a/esphome/components/sensor/pulse_counter.py b/esphome/components/sensor/pulse_counter.py index 067fab5bcb..04b7cee7d5 100644 --- a/esphome/components/sensor/pulse_counter.py +++ b/esphome/components/sensor/pulse_counter.py @@ -4,7 +4,7 @@ from esphome import pins from esphome.components import sensor import esphome.config_validation as cv from esphome.const import CONF_COUNT_MODE, CONF_FALLING_EDGE, CONF_ID, CONF_INTERNAL_FILTER, \ - CONF_NAME, CONF_PIN, CONF_RISING_EDGE, CONF_UPDATE_INTERVAL + CONF_NAME, CONF_PIN, CONF_RISING_EDGE, CONF_UPDATE_INTERVAL, CONF_NUMBER from esphome.core import CORE from esphome.cpp_generator import Pvariable, add from esphome.cpp_helpers import gpio_input_pin_expression, setup_component @@ -38,9 +38,16 @@ def validate_internal_filter(value): return cv.positive_time_period_microseconds(value) +def validate_pulse_counter_pin(value): + value = pins.internal_gpio_input_pin_schema(value) + if CORE.is_esp8266 and value[CONF_NUMBER] >= 16: + raise vol.Invalid("Pins GPIO16 and GPIO17 cannot be used as pulse counters on ESP8266.") + return value + + PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(PulseCounterSensorComponent), - vol.Required(CONF_PIN): pins.internal_gpio_input_pin_schema, + vol.Required(CONF_PIN): validate_pulse_counter_pin, vol.Optional(CONF_COUNT_MODE): cv.Schema({ vol.Required(CONF_RISING_EDGE): COUNT_MODE_SCHEMA, vol.Required(CONF_FALLING_EDGE): COUNT_MODE_SCHEMA, diff --git a/esphome/components/sensor/rotary_encoder.py b/esphome/components/sensor/rotary_encoder.py index 15926599da..72a5c7ccca 100644 --- a/esphome/components/sensor/rotary_encoder.py +++ b/esphome/components/sensor/rotary_encoder.py @@ -34,8 +34,10 @@ def validate_min_max_value(config): PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(RotaryEncoderSensor), - vol.Required(CONF_PIN_A): pins.internal_gpio_input_pin_schema, - vol.Required(CONF_PIN_B): pins.internal_gpio_input_pin_schema, + vol.Required(CONF_PIN_A): vol.All(pins.internal_gpio_input_pin_schema, + pins.validate_has_interrupt), + vol.Required(CONF_PIN_B): vol.All(pins.internal_gpio_input_pin_schema, + pins.validate_has_interrupt), vol.Optional(CONF_PIN_RESET): pins.internal_gpio_input_pin_schema, vol.Optional(CONF_RESOLUTION): cv.one_of(*RESOLUTIONS, int=True), vol.Optional(CONF_MIN_VALUE): cv.int_, diff --git a/esphome/components/sensor/ultrasonic.py b/esphome/components/sensor/ultrasonic.py index 894b7a73dc..b7191ca3f1 100644 --- a/esphome/components/sensor/ultrasonic.py +++ b/esphome/components/sensor/ultrasonic.py @@ -3,23 +3,32 @@ import voluptuous as vol from esphome import pins from esphome.components import sensor import esphome.config_validation as cv -from esphome.const import CONF_ECHO_PIN, CONF_ID, CONF_NAME, CONF_TIMEOUT_METER, \ - CONF_TIMEOUT_TIME, CONF_TRIGGER_PIN, CONF_UPDATE_INTERVAL +from esphome.const import CONF_ECHO_PIN, CONF_ID, CONF_NAME, CONF_TRIGGER_PIN, \ + CONF_UPDATE_INTERVAL, CONF_TIMEOUT from esphome.cpp_generator import Pvariable, add from esphome.cpp_helpers import gpio_input_pin_expression, gpio_output_pin_expression, \ setup_component from esphome.cpp_types import App +CONF_PULSE_TIME = 'pulse_time' + UltrasonicSensorComponent = sensor.sensor_ns.class_('UltrasonicSensorComponent', sensor.PollingSensorComponent) + PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(UltrasonicSensorComponent), vol.Required(CONF_TRIGGER_PIN): pins.gpio_output_pin_schema, vol.Required(CONF_ECHO_PIN): pins.internal_gpio_input_pin_schema, - vol.Exclusive(CONF_TIMEOUT_METER, 'timeout'): cv.positive_float, - vol.Exclusive(CONF_TIMEOUT_TIME, 'timeout'): cv.positive_time_period_microseconds, + + vol.Optional(CONF_TIMEOUT): cv.distance, + vol.Optional(CONF_PULSE_TIME): cv.positive_time_period_microseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval, + + vol.Optional('timeout_meter'): cv.invalid("The timeout_meter option has been renamed " + "to 'timeout'."), + vol.Optional('timeout_time'): cv.invalid("The timeout_time option has been removed. Please " + "use 'timeout'."), })) @@ -32,10 +41,11 @@ def to_code(config): config.get(CONF_UPDATE_INTERVAL)) ultrasonic = Pvariable(config[CONF_ID], rhs) - if CONF_TIMEOUT_TIME in config: - add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT_TIME])) - elif CONF_TIMEOUT_METER in config: - add(ultrasonic.set_timeout_m(config[CONF_TIMEOUT_METER])) + if CONF_TIMEOUT in config: + add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT] / (0.000343 / 2))) + + if CONF_PULSE_TIME in config: + add(ultrasonic.set_pulse_time_us(config[CONF_PULSE_TIME])) sensor.setup_sensor(ultrasonic, config) setup_component(ultrasonic, config) diff --git a/esphome/components/uart.py b/esphome/components/uart.py index 0b15bd66bd..28a9d5cb47 100644 --- a/esphome/components/uart.py +++ b/esphome/components/uart.py @@ -3,6 +3,7 @@ import voluptuous as vol from esphome import pins import esphome.config_validation as cv from esphome.const import CONF_BAUD_RATE, CONF_ID, CONF_RX_PIN, CONF_TX_PIN +from esphome.core import CORE from esphome.cpp_generator import Pvariable, add from esphome.cpp_helpers import setup_component from esphome.cpp_types import App, Component, esphome_ns @@ -11,10 +12,18 @@ UARTComponent = esphome_ns.class_('UARTComponent', Component) UARTDevice = esphome_ns.class_('UARTDevice') MULTI_CONF = True + +def validate_rx_pin(value): + value = pins.input_pin(value) + if CORE.is_esp8266 and value >= 16: + raise vol.Invalid("Pins GPIO16 and GPIO17 cannot be used as RX pins on ESP8266.") + return value + + CONFIG_SCHEMA = vol.All(cv.Schema({ cv.GenerateID(): cv.declare_variable_id(UARTComponent), vol.Optional(CONF_TX_PIN): pins.output_pin, - vol.Optional(CONF_RX_PIN): pins.input_pin, + vol.Optional(CONF_RX_PIN): validate_rx_pin, vol.Required(CONF_BAUD_RATE): cv.positive_int, }).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(CONF_TX_PIN, CONF_RX_PIN)) diff --git a/esphome/config_validation.py b/esphome/config_validation.py index ad7372e738..e82268ae63 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -430,6 +430,7 @@ frequency = float_with_unit("frequency", r"(Hz|HZ|hz)?") resistance = float_with_unit("resistance", r"(Ω|Ω|ohm|Ohm|OHM)?") current = float_with_unit("current", r"(a|A|amp|Amp|amps|Amps|ampere|Ampere)?") voltage = float_with_unit("voltage", r"(v|V|volt|Volts)?") +distance = float_with_unit("distance", r"(m)") def validate_bytes(value): diff --git a/esphome/const.py b/esphome/const.py index a4f6862d5d..b5af7f6b67 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -157,8 +157,7 @@ CONF_ATTENUATION = 'attenuation' CONF_PRESSURE = 'pressure' CONF_TRIGGER_PIN = 'trigger_pin' CONF_ECHO_PIN = 'echo_pin' -CONF_TIMEOUT_METER = 'timeout_meter' -CONF_TIMEOUT_TIME = 'timeout_time' +CONF_TIMEOUT = 'timeout' CONF_CARRIER_DUTY_PERCENT = 'carrier_duty_percent' CONF_NEC = 'nec' CONF_COMMAND = 'command' diff --git a/esphome/core_config.py b/esphome/core_config.py index b505fd53af..579f8973fe 100644 --- a/esphome/core_config.py +++ b/esphome/core_config.py @@ -194,7 +194,7 @@ CONFIG_SCHEMA = cv.Schema({ def preload_core_config(config): if 'esphomeyaml' in config: _LOGGER.warning("The esphomeyaml section has been renamed to esphome in 1.11.0. " - "Please replace 'esphomeyaml:' in your configuration by 'esphome:'.") + "Please replace 'esphomeyaml:' in your configuration with 'esphome:'.") config[CONF_ESPHOME] = config.pop('esphomeyaml') if CONF_ESPHOME not in config: raise EsphomeError(u"No esphome section in config") diff --git a/esphome/pins.py b/esphome/pins.py index 7542018783..06b7fdd52f 100644 --- a/esphome/pins.py +++ b/esphome/pins.py @@ -348,6 +348,14 @@ def shorthand_input_pullup_pin(value): return {CONF_NUMBER: value} +def validate_has_interrupt(value): + if CORE.is_esp8266: + if value[CONF_NUMBER] >= 16: + raise vol.Invalid("Pins GPIO16 and GPIO17 do not support interrupts and cannot be used " + "here, got {}".format(value[CONF_NUMBER])) + return value + + I2CDevice = esphome_ns.class_('I2CDevice') PCF8574Component = io_ns.class_('PCF8574Component', Component, I2CDevice) diff --git a/tests/test1.yaml b/tests/test1.yaml index f09dafda50..a1f26f7573 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -475,7 +475,7 @@ sensor: number: GPIO23 inverted: true name: "Ultrasonic Sensor" - timeout_meter: 5.5 + timeout: 5.5m id: ultrasonic_sensor1 - platform: uptime name: Uptime Sensor