Recommend similar keys for spelling errors (#458)

* Recommend similar keys for spelling errors

Fixes https://github.com/esphome/feature-requests/issues/68

* Fixes

* Fix
This commit is contained in:
Otto Winter 2019-02-26 19:22:33 +01:00 committed by GitHub
parent 38e7b597d6
commit 1c7ca4bc6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 302 additions and 137 deletions

View file

@ -131,7 +131,7 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
# Next try as a sequence of automations # Next try as a sequence of automations
try: try:
return vol.Schema([schema])(value) return cv.Schema([schema])(value)
except vol.Invalid as err2: except vol.Invalid as err2:
if 'Unable to find action' in str(err): if 'Unable to find action' in str(err):
raise err2 raise err2
@ -146,7 +146,7 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
def validator(value): def validator(value):
value = validator_(value) value = validator_(value)
if extra_validators is not None: if extra_validators is not None:
value = vol.Schema([extra_validators])(value) value = cv.Schema([extra_validators])(value)
if single: if single:
if len(value) != 1: if len(value) != 1:
raise vol.Invalid("Cannot have more than 1 automation for templates") raise vol.Invalid("Cannot have more than 1 automation for templates")
@ -156,7 +156,7 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
return validator return validator
AUTOMATION_SCHEMA = vol.Schema({ AUTOMATION_SCHEMA = cv.Schema({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(Trigger), cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(Trigger),
cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(Automation), cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(Automation),
vol.Optional(CONF_IF): validate_recursive_condition, vol.Optional(CONF_IF): validate_recursive_condition,
@ -187,7 +187,7 @@ def or_condition_to_code(config, condition_id, arg_type, template_arg):
yield Pvariable(condition_id, rhs, type=type) yield Pvariable(condition_id, rhs, type=type)
RANGE_CONDITION_SCHEMA = vol.All(vol.Schema({ RANGE_CONDITION_SCHEMA = vol.All(cv.Schema({
vol.Optional(CONF_ABOVE): cv.templatable(cv.float_), vol.Optional(CONF_ABOVE): cv.templatable(cv.float_),
vol.Optional(CONF_BELOW): cv.templatable(cv.float_), vol.Optional(CONF_BELOW): cv.templatable(cv.float_),
}), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW)) }), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW))
@ -250,7 +250,7 @@ def if_action_to_code(config, action_id, arg_type, template_arg):
yield action yield action
WHILE_ACTION_SCHEMA = vol.Schema({ WHILE_ACTION_SCHEMA = cv.Schema({
vol.Required(CONF_CONDITION): validate_recursive_condition, vol.Required(CONF_CONDITION): validate_recursive_condition,
vol.Required(CONF_THEN): validate_recursive_action, vol.Required(CONF_THEN): validate_recursive_action,
}) })
@ -270,7 +270,7 @@ def while_action_to_code(config, action_id, arg_type, template_arg):
def validate_wait_until(value): def validate_wait_until(value):
schema = vol.Schema({ schema = cv.Schema({
vol.Required(CONF_CONDITION): validate_recursive_condition vol.Required(CONF_CONDITION): validate_recursive_condition
}) })
if isinstance(value, dict) and CONF_CONDITION in value: if isinstance(value, dict) and CONF_CONDITION in value:

View file

@ -12,7 +12,7 @@ MULTI_CONF = True
ADS1115Component = sensor.sensor_ns.class_('ADS1115Component', Component, i2c.I2CDevice) ADS1115Component = sensor.sensor_ns.class_('ADS1115Component', Component, i2c.I2CDevice)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(ADS1115Component), cv.GenerateID(): cv.declare_variable_id(ADS1115Component),
vol.Required(CONF_ADDRESS): cv.i2c_address, vol.Required(CONF_ADDRESS): cv.i2c_address,
}).extend(cv.COMPONENT_SCHEMA.schema) }).extend(cv.COMPONENT_SCHEMA.schema)

View file

@ -13,7 +13,7 @@ MULTI_CONF = True
CONF_APDS9960_ID = 'apds9960_id' CONF_APDS9960_ID = 'apds9960_id'
APDS9960 = sensor.sensor_ns.class_('APDS9960', PollingComponent, i2c.I2CDevice) APDS9960 = sensor.sensor_ns.class_('APDS9960', PollingComponent, i2c.I2CDevice)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(APDS9960), cv.GenerateID(): cv.declare_variable_id(APDS9960),
vol.Optional(CONF_ADDRESS): cv.i2c_address, vol.Optional(CONF_ADDRESS): cv.i2c_address,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval, vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,

View file

@ -15,7 +15,7 @@ HomeAssistantServiceCallAction = api_ns.class_('HomeAssistantServiceCallAction',
KeyValuePair = api_ns.class_('KeyValuePair') KeyValuePair = api_ns.class_('KeyValuePair')
TemplatableKeyValuePair = api_ns.class_('TemplatableKeyValuePair') TemplatableKeyValuePair = api_ns.class_('TemplatableKeyValuePair')
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(APIServer), cv.GenerateID(): cv.declare_variable_id(APIServer),
vol.Optional(CONF_PORT, default=6053): cv.port, vol.Optional(CONF_PORT, default=6053): cv.port,
vol.Optional(CONF_PASSWORD, default=''): cv.string_strict, vol.Optional(CONF_PASSWORD, default=''): cv.string_strict,
@ -49,16 +49,16 @@ def lib_deps(config):
CONF_HOMEASSISTANT_SERVICE = 'homeassistant.service' CONF_HOMEASSISTANT_SERVICE = 'homeassistant.service'
HOMEASSISTANT_SERVIC_ACTION_SCHEMA = vol.Schema({ HOMEASSISTANT_SERVIC_ACTION_SCHEMA = cv.Schema({
cv.GenerateID(): cv.use_variable_id(APIServer), cv.GenerateID(): cv.use_variable_id(APIServer),
vol.Required(CONF_SERVICE): cv.string, vol.Required(CONF_SERVICE): cv.string,
vol.Optional(CONF_DATA): vol.Schema({ vol.Optional(CONF_DATA): cv.Schema({
cv.string: cv.string, cv.string: cv.string,
}), }),
vol.Optional(CONF_DATA_TEMPLATE): vol.Schema({ vol.Optional(CONF_DATA_TEMPLATE): cv.Schema({
cv.string: cv.string, cv.string: cv.string,
}), }),
vol.Optional(CONF_VARIABLES): vol.Schema({ vol.Optional(CONF_VARIABLES): cv.Schema({
cv.string: cv.lambda_, cv.string: cv.lambda_,
}), }),
}) })

View file

@ -62,7 +62,7 @@ FILTERS_SCHEMA = cv.ensure_list({
vol.Optional(CONF_HEARTBEAT): cv.invalid("The heartbeat filter has been removed in 1.11.0"), vol.Optional(CONF_HEARTBEAT): cv.invalid("The heartbeat filter has been removed in 1.11.0"),
}, cv.has_exactly_one_key(*FILTER_KEYS)) }, cv.has_exactly_one_key(*FILTER_KEYS))
MULTI_CLICK_TIMING_SCHEMA = vol.Schema({ MULTI_CLICK_TIMING_SCHEMA = cv.Schema({
vol.Optional(CONF_STATE): cv.boolean, vol.Optional(CONF_STATE): cv.boolean,
vol.Optional(CONF_MIN_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_MIN_LENGTH): cv.positive_time_period_milliseconds,
vol.Optional(CONF_MAX_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_MAX_LENGTH): cv.positive_time_period_milliseconds,

View file

@ -41,7 +41,7 @@ RCSwitchTypeDReceiver = remote_ns.class_('RCSwitchTypeDReceiver', RCSwitchRawRec
def validate_raw(value): def validate_raw(value):
if isinstance(value, dict): if isinstance(value, dict):
return vol.Schema({ return cv.Schema({
cv.GenerateID(): cv.declare_variable_id(int32), cv.GenerateID(): cv.declare_variable_id(int32),
vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)], vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
})(value) })(value)
@ -52,29 +52,29 @@ def validate_raw(value):
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(RemoteReceiver), cv.GenerateID(): cv.declare_variable_id(RemoteReceiver),
vol.Optional(CONF_JVC): vol.Schema({ vol.Optional(CONF_JVC): cv.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t, vol.Required(CONF_DATA): cv.hex_uint32_t,
}), }),
vol.Optional(CONF_LG): vol.Schema({ vol.Optional(CONF_LG): cv.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t, vol.Required(CONF_DATA): cv.hex_uint32_t,
vol.Optional(CONF_NBITS, default=28): cv.one_of(28, 32, int=True), vol.Optional(CONF_NBITS, default=28): cv.one_of(28, 32, int=True),
}), }),
vol.Optional(CONF_NEC): vol.Schema({ vol.Optional(CONF_NEC): cv.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,
}), }),
vol.Optional(CONF_SAMSUNG): vol.Schema({ vol.Optional(CONF_SAMSUNG): cv.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t, vol.Required(CONF_DATA): cv.hex_uint32_t,
}), }),
vol.Optional(CONF_SONY): vol.Schema({ vol.Optional(CONF_SONY): cv.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t, vol.Required(CONF_DATA): cv.hex_uint32_t,
vol.Optional(CONF_NBITS, default=12): cv.one_of(12, 15, 20, int=True), vol.Optional(CONF_NBITS, default=12): cv.one_of(12, 15, 20, int=True),
}), }),
vol.Optional(CONF_PANASONIC): vol.Schema({ vol.Optional(CONF_PANASONIC): cv.Schema({
vol.Required(CONF_ADDRESS): cv.hex_uint16_t, vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
vol.Required(CONF_COMMAND): cv.hex_uint32_t, vol.Required(CONF_COMMAND): cv.hex_uint32_t,
}), }),
vol.Optional(CONF_RC5): vol.Schema({ vol.Optional(CONF_RC5): cv.Schema({
vol.Required(CONF_ADDRESS): vol.All(cv.hex_int, vol.Range(min=0, max=0x1F)), vol.Required(CONF_ADDRESS): vol.All(cv.hex_int, vol.Range(min=0, max=0x1F)),
vol.Required(CONF_COMMAND): vol.All(cv.hex_int, vol.Range(min=0, max=0x3F)), vol.Required(CONF_COMMAND): vol.All(cv.hex_int, vol.Range(min=0, max=0x3F)),
}), }),

View file

@ -36,7 +36,7 @@ def to_code(config):
BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR' BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR'
CONF_BINARY_SENSOR_TEMPLATE_PUBLISH = 'binary_sensor.template.publish' CONF_BINARY_SENSOR_TEMPLATE_PUBLISH = 'binary_sensor.template.publish'
BINARY_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({ BINARY_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.use_variable_id(binary_sensor.BinarySensor), vol.Required(CONF_ID): cv.use_variable_id(binary_sensor.BinarySensor),
vol.Required(CONF_STATE): cv.templatable(cv.boolean), vol.Required(CONF_STATE): cv.templatable(cv.boolean),
}) })

View file

@ -55,7 +55,7 @@ def to_code(config):
BUILD_FLAGS = '-DUSE_TEMPLATE_COVER' BUILD_FLAGS = '-DUSE_TEMPLATE_COVER'
CONF_COVER_TEMPLATE_PUBLISH = 'cover.template.publish' CONF_COVER_TEMPLATE_PUBLISH = 'cover.template.publish'
COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({ COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.use_variable_id(cover.Cover), vol.Required(CONF_ID): cv.use_variable_id(cover.Cover),
vol.Required(CONF_STATE): cv.templatable(cover.validate_cover_state), vol.Required(CONF_STATE): cv.templatable(cover.validate_cover_state),
}) })

View file

@ -9,10 +9,10 @@ from esphome.cpp_types import Component, ComponentPtr, esphome_ns, std_vector
CustomComponentConstructor = esphome_ns.class_('CustomComponentConstructor') CustomComponentConstructor = esphome_ns.class_('CustomComponentConstructor')
MULTI_CONF = True MULTI_CONF = True
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(CustomComponentConstructor), cv.GenerateID(): cv.declare_variable_id(CustomComponentConstructor),
vol.Required(CONF_LAMBDA): cv.lambda_, vol.Required(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_COMPONENTS): cv.ensure_list(vol.Schema({ vol.Optional(CONF_COMPONENTS): cv.ensure_list(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(Component) cv.GenerateID(): cv.declare_variable_id(Component)
}).extend(cv.COMPONENT_SCHEMA.schema)), }).extend(cv.COMPONENT_SCHEMA.schema)),
}) })

View file

@ -11,7 +11,7 @@ from esphome.cpp_types import App, PollingComponent
DallasComponent = sensor.sensor_ns.class_('DallasComponent', PollingComponent) DallasComponent = sensor.sensor_ns.class_('DallasComponent', PollingComponent)
MULTI_CONF = True MULTI_CONF = True
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(DallasComponent), cv.GenerateID(): cv.declare_variable_id(DallasComponent),
vol.Required(CONF_PIN): pins.input_pin, vol.Required(CONF_PIN): pins.input_pin,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval, vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,

View file

@ -1,11 +1,10 @@
import voluptuous as vol import esphome.config_validation as cv
from esphome.cpp_generator import add from esphome.cpp_generator import add
from esphome.cpp_types import App from esphome.cpp_types import App
DEPENDENCIES = ['logger'] DEPENDENCIES = ['logger']
CONFIG_SCHEMA = vol.Schema({}) CONFIG_SCHEMA = cv.Schema({})
def to_code(config): def to_code(config):

View file

@ -38,14 +38,14 @@ EXT1_WAKEUP_MODES = {
CONF_WAKEUP_PIN_MODE = 'wakeup_pin_mode' CONF_WAKEUP_PIN_MODE = 'wakeup_pin_mode'
CONF_ESP32_EXT1_WAKEUP = 'esp32_ext1_wakeup' CONF_ESP32_EXT1_WAKEUP = 'esp32_ext1_wakeup'
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(DeepSleepComponent), cv.GenerateID(): cv.declare_variable_id(DeepSleepComponent),
vol.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds, vol.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds,
vol.Optional(CONF_WAKEUP_PIN): vol.All(cv.only_on_esp32, pins.internal_gpio_input_pin_schema, vol.Optional(CONF_WAKEUP_PIN): vol.All(cv.only_on_esp32, pins.internal_gpio_input_pin_schema,
validate_pin_number), validate_pin_number),
vol.Optional(CONF_WAKEUP_PIN_MODE): vol.All(cv.only_on_esp32, vol.Optional(CONF_WAKEUP_PIN_MODE): vol.All(cv.only_on_esp32,
cv.one_of(*WAKEUP_PIN_MODES), upper=True), cv.one_of(*WAKEUP_PIN_MODES), upper=True),
vol.Optional(CONF_ESP32_EXT1_WAKEUP): vol.All(cv.only_on_esp32, vol.Schema({ vol.Optional(CONF_ESP32_EXT1_WAKEUP): vol.All(cv.only_on_esp32, cv.Schema({
vol.Required(CONF_PINS): cv.ensure_list(pins.shorthand_input_pin, validate_pin_number), vol.Required(CONF_PINS): cv.ensure_list(pins.shorthand_input_pin, validate_pin_number),
vol.Required(CONF_MODE): cv.one_of(*EXT1_WAKEUP_MODES, upper=True), vol.Required(CONF_MODE): cv.one_of(*EXT1_WAKEUP_MODES, upper=True),
})), })),

View file

@ -13,7 +13,7 @@ ESP32BLEBeacon = esphome_ns.class_('ESP32BLEBeacon', Component)
CONF_MAJOR = 'major' CONF_MAJOR = 'major'
CONF_MINOR = 'minor' CONF_MINOR = 'minor'
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(ESP32BLEBeacon), cv.GenerateID(): cv.declare_variable_id(ESP32BLEBeacon),
vol.Required(CONF_TYPE): cv.one_of('IBEACON', upper=True), vol.Required(CONF_TYPE): cv.one_of('IBEACON', upper=True),
vol.Required(CONF_UUID): cv.uuid, vol.Required(CONF_UUID): cv.uuid,

View file

@ -18,7 +18,7 @@ XIAOMI_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(XiaomiSensor) cv.GenerateID(): cv.declare_variable_id(XiaomiSensor)
}) })
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker), cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker),
vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_seconds, vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_seconds,
}).extend(cv.COMPONENT_SCHEMA.schema) }).extend(cv.COMPONENT_SCHEMA.schema)

View file

@ -46,7 +46,7 @@ VOLTAGE_ATTENUATION = {
ESP32TouchComponent = binary_sensor.binary_sensor_ns.class_('ESP32TouchComponent', Component) ESP32TouchComponent = binary_sensor.binary_sensor_ns.class_('ESP32TouchComponent', Component)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(ESP32TouchComponent), cv.GenerateID(): cv.declare_variable_id(ESP32TouchComponent),
vol.Optional(CONF_SETUP_MODE): cv.boolean, vol.Optional(CONF_SETUP_MODE): cv.boolean,
vol.Optional(CONF_IIR_FILTER): cv.positive_time_period_milliseconds, vol.Optional(CONF_IIR_FILTER): cv.positive_time_period_milliseconds,

View file

@ -46,7 +46,7 @@ def validate(config):
return config return config
CONFIG_SCHEMA = vol.All(vol.Schema({ CONFIG_SCHEMA = vol.All(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(EthernetComponent), cv.GenerateID(): cv.declare_variable_id(EthernetComponent),
vol.Required(CONF_TYPE): cv.one_of(*ETHERNET_TYPES, upper=True), vol.Required(CONF_TYPE): cv.one_of(*ETHERNET_TYPES, upper=True),
vol.Required(CONF_MDC_PIN): pins.output_pin, vol.Required(CONF_MDC_PIN): pins.output_pin,

View file

@ -14,7 +14,7 @@ PLATFORM_SCHEMA = cv.nameable(fan.FAN_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_SPEED_STATE_TOPIC): cv.publish_topic, vol.Optional(CONF_SPEED_STATE_TOPIC): cv.publish_topic,
vol.Optional(CONF_SPEED_COMMAND_TOPIC): cv.subscribe_topic, vol.Optional(CONF_SPEED_COMMAND_TOPIC): cv.subscribe_topic,
vol.Optional(CONF_OSCILLATION_OUTPUT): cv.use_variable_id(output.BinaryOutput), vol.Optional(CONF_OSCILLATION_OUTPUT): cv.use_variable_id(output.BinaryOutput),
vol.Optional(CONF_SPEED): vol.Schema({ vol.Optional(CONF_SPEED): cv.Schema({
vol.Required(CONF_LOW): cv.percentage, vol.Required(CONF_LOW): cv.percentage,
vol.Required(CONF_MEDIUM): cv.percentage, vol.Required(CONF_MEDIUM): cv.percentage,
vol.Required(CONF_HIGH): cv.percentage, vol.Required(CONF_HIGH): cv.percentage,

View file

@ -19,8 +19,8 @@ Glyph = display.display_ns.class_('Glyph')
def validate_glyphs(value): def validate_glyphs(value):
if isinstance(value, list): if isinstance(value, list):
value = vol.Schema([cv.string])(value) value = cv.Schema([cv.string])(value)
value = vol.Schema([cv.string])(list(value)) value = cv.Schema([cv.string])(list(value))
def comparator(x, y): def comparator(x, y):
x_ = x.encode('utf-8') x_ = x.encode('utf-8')
@ -69,7 +69,7 @@ def validate_truetype_file(value):
DEFAULT_GLYPHS = u' !"%()+,-.:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz°' DEFAULT_GLYPHS = u' !"%()+,-.:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz°'
CONF_RAW_DATA_ID = 'raw_data_id' CONF_RAW_DATA_ID = 'raw_data_id'
FONT_SCHEMA = vol.Schema({ FONT_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.declare_variable_id(Font), vol.Required(CONF_ID): cv.declare_variable_id(Font),
vol.Required(CONF_FILE): validate_truetype_file, vol.Required(CONF_FILE): validate_truetype_file,
vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs, vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs,

View file

@ -10,7 +10,7 @@ GlobalVariableComponent = esphome_ns.class_('GlobalVariableComponent', Component
MULTI_CONF = True MULTI_CONF = True
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.declare_variable_id(GlobalVariableComponent), vol.Required(CONF_ID): cv.declare_variable_id(GlobalVariableComponent),
vol.Required(CONF_TYPE): cv.string_strict, vol.Required(CONF_TYPE): cv.string_strict,
vol.Optional(CONF_INITIAL_VALUE): cv.string_strict, vol.Optional(CONF_INITIAL_VALUE): cv.string_strict,

View file

@ -11,7 +11,7 @@ from esphome.cpp_types import App, Component, esphome_ns
I2CComponent = esphome_ns.class_('I2CComponent', Component) I2CComponent = esphome_ns.class_('I2CComponent', Component)
I2CDevice = pins.I2CDevice I2CDevice = pins.I2CDevice
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(I2CComponent), cv.GenerateID(): cv.declare_variable_id(I2CComponent),
vol.Optional(CONF_SDA, default='SDA'): pins.input_pin, vol.Optional(CONF_SDA, default='SDA'): pins.input_pin,
vol.Optional(CONF_SCL, default='SCL'): pins.input_pin, vol.Optional(CONF_SCL, default='SCL'): pins.input_pin,

View file

@ -20,7 +20,7 @@ Image_ = display.display_ns.class_('Image')
CONF_RAW_DATA_ID = 'raw_data_id' CONF_RAW_DATA_ID = 'raw_data_id'
IMAGE_SCHEMA = vol.Schema({ IMAGE_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.declare_variable_id(Image_), vol.Required(CONF_ID): cv.declare_variable_id(Image_),
vol.Required(CONF_FILE): cv.file_, vol.Required(CONF_FILE): cv.file_,
vol.Optional(CONF_RESIZE): cv.dimensions, vol.Optional(CONF_RESIZE): cv.dimensions,

View file

@ -9,7 +9,7 @@ from esphome.cpp_types import App, NoArg, PollingComponent, Trigger, esphome_ns
IntervalTrigger = esphome_ns.class_('IntervalTrigger', Trigger.template(NoArg), PollingComponent) IntervalTrigger = esphome_ns.class_('IntervalTrigger', Trigger.template(NoArg), PollingComponent)
CONFIG_SCHEMA = automation.validate_automation(vol.Schema({ CONFIG_SCHEMA = automation.validate_automation(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(IntervalTrigger), cv.GenerateID(): cv.declare_variable_id(IntervalTrigger),
vol.Required(CONF_INTERVAL): cv.positive_time_period_milliseconds, vol.Required(CONF_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(cv.COMPONENT_SCHEMA.schema)) }).extend(cv.COMPONENT_SCHEMA.schema))

View file

@ -88,22 +88,22 @@ ADDRESSABLE_EFFECTS = RGB_EFFECTS + [CONF_ADDRESSABLE_LAMBDA, CONF_ADDRESSABLE_R
CONF_ADDRESSABLE_TWINKLE, CONF_ADDRESSABLE_RANDOM_TWINKLE, CONF_ADDRESSABLE_TWINKLE, CONF_ADDRESSABLE_RANDOM_TWINKLE,
CONF_ADDRESSABLE_FIREWORKS, CONF_ADDRESSABLE_FLICKER] CONF_ADDRESSABLE_FIREWORKS, CONF_ADDRESSABLE_FLICKER]
EFFECTS_SCHEMA = vol.Schema({ EFFECTS_SCHEMA = cv.Schema({
vol.Optional(CONF_LAMBDA): vol.Schema({ vol.Optional(CONF_LAMBDA): cv.Schema({
vol.Required(CONF_NAME): cv.string, vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_LAMBDA): cv.lambda_, vol.Required(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_UPDATE_INTERVAL, default='0ms'): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL, default='0ms'): cv.positive_time_period_milliseconds,
}), }),
vol.Optional(CONF_RANDOM): vol.Schema({ vol.Optional(CONF_RANDOM): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(RandomLightEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(RandomLightEffect),
vol.Optional(CONF_NAME, default="Random"): cv.string, vol.Optional(CONF_NAME, default="Random"): cv.string,
vol.Optional(CONF_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}), }),
vol.Optional(CONF_STROBE): vol.Schema({ vol.Optional(CONF_STROBE): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(StrobeLightEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(StrobeLightEffect),
vol.Optional(CONF_NAME, default="Strobe"): cv.string, vol.Optional(CONF_NAME, default="Strobe"): cv.string,
vol.Optional(CONF_COLORS): vol.All(cv.ensure_list(vol.Schema({ vol.Optional(CONF_COLORS): vol.All(cv.ensure_list(cv.Schema({
vol.Optional(CONF_STATE, default=True): cv.boolean, vol.Optional(CONF_STATE, default=True): cv.boolean,
vol.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage, vol.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
vol.Optional(CONF_RED, default=1.0): cv.percentage, vol.Optional(CONF_RED, default=1.0): cv.percentage,
@ -114,24 +114,24 @@ EFFECTS_SCHEMA = vol.Schema({
}), cv.has_at_least_one_key(CONF_STATE, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE, }), cv.has_at_least_one_key(CONF_STATE, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE,
CONF_WHITE)), vol.Length(min=2)), CONF_WHITE)), vol.Length(min=2)),
}), }),
vol.Optional(CONF_FLICKER): vol.Schema({ vol.Optional(CONF_FLICKER): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FlickerLightEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FlickerLightEffect),
vol.Optional(CONF_NAME, default="Flicker"): cv.string, vol.Optional(CONF_NAME, default="Flicker"): cv.string,
vol.Optional(CONF_ALPHA): cv.percentage, vol.Optional(CONF_ALPHA): cv.percentage,
vol.Optional(CONF_INTENSITY): cv.percentage, vol.Optional(CONF_INTENSITY): cv.percentage,
}), }),
vol.Optional(CONF_ADDRESSABLE_LAMBDA): vol.Schema({ vol.Optional(CONF_ADDRESSABLE_LAMBDA): cv.Schema({
vol.Required(CONF_NAME): cv.string, vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_LAMBDA): cv.lambda_, vol.Required(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_UPDATE_INTERVAL, default='0ms'): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL, default='0ms'): cv.positive_time_period_milliseconds,
}), }),
vol.Optional(CONF_ADDRESSABLE_RAINBOW): vol.Schema({ vol.Optional(CONF_ADDRESSABLE_RAINBOW): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableRainbowLightEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableRainbowLightEffect),
vol.Optional(CONF_NAME, default="Rainbow"): cv.string, vol.Optional(CONF_NAME, default="Rainbow"): cv.string,
vol.Optional(CONF_SPEED): cv.uint32_t, vol.Optional(CONF_SPEED): cv.uint32_t,
vol.Optional(CONF_WIDTH): cv.uint32_t, vol.Optional(CONF_WIDTH): cv.uint32_t,
}), }),
vol.Optional(CONF_ADDRESSABLE_COLOR_WIPE): vol.Schema({ vol.Optional(CONF_ADDRESSABLE_COLOR_WIPE): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableColorWipeEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableColorWipeEffect),
vol.Optional(CONF_NAME, default="Color Wipe"): cv.string, vol.Optional(CONF_NAME, default="Color Wipe"): cv.string,
vol.Optional(CONF_COLORS): cv.ensure_list({ vol.Optional(CONF_COLORS): cv.ensure_list({
@ -145,24 +145,24 @@ EFFECTS_SCHEMA = vol.Schema({
vol.Optional(CONF_ADD_LED_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_ADD_LED_INTERVAL): cv.positive_time_period_milliseconds,
vol.Optional(CONF_REVERSE): cv.boolean, vol.Optional(CONF_REVERSE): cv.boolean,
}), }),
vol.Optional(CONF_ADDRESSABLE_SCAN): vol.Schema({ vol.Optional(CONF_ADDRESSABLE_SCAN): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableScanEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableScanEffect),
vol.Optional(CONF_NAME, default="Scan"): cv.string, vol.Optional(CONF_NAME, default="Scan"): cv.string,
vol.Optional(CONF_MOVE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_MOVE_INTERVAL): cv.positive_time_period_milliseconds,
}), }),
vol.Optional(CONF_ADDRESSABLE_TWINKLE): vol.Schema({ vol.Optional(CONF_ADDRESSABLE_TWINKLE): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableTwinkleEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableTwinkleEffect),
vol.Optional(CONF_NAME, default="Twinkle"): cv.string, vol.Optional(CONF_NAME, default="Twinkle"): cv.string,
vol.Optional(CONF_TWINKLE_PROBABILITY): cv.percentage, vol.Optional(CONF_TWINKLE_PROBABILITY): cv.percentage,
vol.Optional(CONF_PROGRESS_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_PROGRESS_INTERVAL): cv.positive_time_period_milliseconds,
}), }),
vol.Optional(CONF_ADDRESSABLE_RANDOM_TWINKLE): vol.Schema({ vol.Optional(CONF_ADDRESSABLE_RANDOM_TWINKLE): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableRandomTwinkleEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableRandomTwinkleEffect),
vol.Optional(CONF_NAME, default="Random Twinkle"): cv.string, vol.Optional(CONF_NAME, default="Random Twinkle"): cv.string,
vol.Optional(CONF_TWINKLE_PROBABILITY): cv.percentage, vol.Optional(CONF_TWINKLE_PROBABILITY): cv.percentage,
vol.Optional(CONF_PROGRESS_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_PROGRESS_INTERVAL): cv.positive_time_period_milliseconds,
}), }),
vol.Optional(CONF_ADDRESSABLE_FIREWORKS): vol.Schema({ vol.Optional(CONF_ADDRESSABLE_FIREWORKS): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableFireworksEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableFireworksEffect),
vol.Optional(CONF_NAME, default="Fireworks"): cv.string, vol.Optional(CONF_NAME, default="Fireworks"): cv.string,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
@ -170,7 +170,7 @@ EFFECTS_SCHEMA = vol.Schema({
vol.Optional(CONF_USE_RANDOM_COLOR): cv.boolean, vol.Optional(CONF_USE_RANDOM_COLOR): cv.boolean,
vol.Optional(CONF_FADE_OUT_RATE): cv.uint8_t, vol.Optional(CONF_FADE_OUT_RATE): cv.uint8_t,
}), }),
vol.Optional(CONF_ADDRESSABLE_FLICKER): vol.Schema({ vol.Optional(CONF_ADDRESSABLE_FLICKER): cv.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableFlickerEffect), cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableFlickerEffect),
vol.Optional(CONF_NAME, default="Addressable Flicker"): cv.string, vol.Optional(CONF_NAME, default="Addressable Flicker"): cv.string,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,

View file

@ -73,13 +73,13 @@ def validate_local_no_higher_than_global(value):
LogComponent = esphome_ns.class_('LogComponent', Component) LogComponent = esphome_ns.class_('LogComponent', Component)
CONFIG_SCHEMA = vol.All(vol.Schema({ CONFIG_SCHEMA = vol.All(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(LogComponent), cv.GenerateID(): cv.declare_variable_id(LogComponent),
vol.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int, vol.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int,
vol.Optional(CONF_TX_BUFFER_SIZE, default=512): cv.validate_bytes, vol.Optional(CONF_TX_BUFFER_SIZE, default=512): cv.validate_bytes,
vol.Optional(CONF_HARDWARE_UART, default='UART0'): uart_selection, vol.Optional(CONF_HARDWARE_UART, default='UART0'): uart_selection,
vol.Optional(CONF_LEVEL): is_log_level, vol.Optional(CONF_LEVEL): is_log_level,
vol.Optional(CONF_LOGS): vol.Schema({ vol.Optional(CONF_LOGS): cv.Schema({
cv.string: is_log_level, cv.string: is_log_level,
}) })
}), validate_local_no_higher_than_global) }), validate_local_no_higher_than_global)
@ -129,8 +129,8 @@ def required_build_flags(config):
def maybe_simple_message(schema): def maybe_simple_message(schema):
def validator(value): def validator(value):
if isinstance(value, dict): if isinstance(value, dict):
return vol.Schema(schema)(value) return cv.Schema(schema)(value)
return vol.Schema(schema)({CONF_FORMAT: value}) return cv.Schema(schema)({CONF_FORMAT: value})
return validator return validator

View file

@ -13,7 +13,7 @@ MULTI_CONF = True
CONF_MPR121_ID = 'mpr121_id' CONF_MPR121_ID = 'mpr121_id'
MPR121Component = binary_sensor.binary_sensor_ns.class_('MPR121Component', Component, i2c.I2CDevice) MPR121Component = binary_sensor.binary_sensor_ns.class_('MPR121Component', Component, i2c.I2CDevice)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(MPR121Component), cv.GenerateID(): cv.declare_variable_id(MPR121Component),
vol.Optional(CONF_ADDRESS): cv.i2c_address vol.Optional(CONF_ADDRESS): cv.i2c_address
}).extend(cv.COMPONENT_SCHEMA.schema) }).extend(cv.COMPONENT_SCHEMA.schema)

View file

@ -26,7 +26,7 @@ def validate_message_just_topic(value):
return MQTT_MESSAGE_BASE({CONF_TOPIC: value}) return MQTT_MESSAGE_BASE({CONF_TOPIC: value})
MQTT_MESSAGE_BASE = vol.Schema({ MQTT_MESSAGE_BASE = cv.Schema({
vol.Required(CONF_TOPIC): cv.publish_topic, vol.Required(CONF_TOPIC): cv.publish_topic,
vol.Optional(CONF_QOS, default=0): cv.mqtt_qos, vol.Optional(CONF_QOS, default=0): cv.mqtt_qos,
vol.Optional(CONF_RETAIN, default=True): cv.boolean, vol.Optional(CONF_RETAIN, default=True): cv.boolean,
@ -67,7 +67,7 @@ def validate_fingerprint(value):
return value return value
CONFIG_SCHEMA = vol.All(vol.Schema({ CONFIG_SCHEMA = vol.All(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(MQTTClientComponent), cv.GenerateID(): cv.declare_variable_id(MQTTClientComponent),
vol.Required(CONF_BROKER): cv.string_strict, vol.Required(CONF_BROKER): cv.string_strict,
vol.Optional(CONF_PORT): cv.port, vol.Optional(CONF_PORT): cv.port,
@ -193,7 +193,7 @@ def to_code(config):
CONF_MQTT_PUBLISH = 'mqtt.publish' CONF_MQTT_PUBLISH = 'mqtt.publish'
MQTT_PUBLISH_ACTION_SCHEMA = vol.Schema({ MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema({
cv.GenerateID(): cv.use_variable_id(MQTTClientComponent), cv.GenerateID(): cv.use_variable_id(MQTTClientComponent),
vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic), vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
vol.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload), vol.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
@ -228,7 +228,7 @@ def mqtt_publish_action_to_code(config, action_id, arg_type, template_arg):
CONF_MQTT_PUBLISH_JSON = 'mqtt.publish_json' CONF_MQTT_PUBLISH_JSON = 'mqtt.publish_json'
MQTT_PUBLISH_JSON_ACTION_SCHEMA = vol.Schema({ MQTT_PUBLISH_JSON_ACTION_SCHEMA = cv.Schema({
cv.GenerateID(): cv.use_variable_id(MQTTClientComponent), cv.GenerateID(): cv.use_variable_id(MQTTClientComponent),
vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic), vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
vol.Required(CONF_PAYLOAD): cv.lambda_, vol.Required(CONF_PAYLOAD): cv.lambda_,

View file

@ -12,7 +12,7 @@ from esphome.cpp_types import App, Component
MY9231OutputComponent = output.output_ns.class_('MY9231OutputComponent', Component) MY9231OutputComponent = output.output_ns.class_('MY9231OutputComponent', Component)
MULTI_CONF = True MULTI_CONF = True
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(MY9231OutputComponent), cv.GenerateID(): cv.declare_variable_id(MY9231OutputComponent),
vol.Required(CONF_DATA_PIN): pins.gpio_output_pin_schema, vol.Required(CONF_DATA_PIN): pins.gpio_output_pin_schema,
vol.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema, vol.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema,

View file

@ -12,7 +12,7 @@ _LOGGER = logging.getLogger(__name__)
OTAComponent = esphome_ns.class_('OTAComponent', Component) OTAComponent = esphome_ns.class_('OTAComponent', Component)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(OTAComponent), cv.GenerateID(): cv.declare_variable_id(OTAComponent),
vol.Optional(CONF_SAFE_MODE, default=True): cv.boolean, vol.Optional(CONF_SAFE_MODE, default=True): cv.boolean,
vol.Optional(CONF_PORT): cv.port, vol.Optional(CONF_PORT): cv.port,

View file

@ -13,7 +13,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
}) })
BINARY_OUTPUT_SCHEMA = vol.Schema({ BINARY_OUTPUT_SCHEMA = cv.Schema({
vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent), vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent),
vol.Optional(CONF_INVERTED): cv.boolean, vol.Optional(CONF_INVERTED): cv.boolean,
}) })
@ -95,7 +95,7 @@ def output_turn_off_to_code(config, action_id, arg_type, template_arg):
CONF_OUTPUT_SET_LEVEL = 'output.set_level' CONF_OUTPUT_SET_LEVEL = 'output.set_level'
OUTPUT_SET_LEVEL_ACTION = vol.Schema({ OUTPUT_SET_LEVEL_ACTION = cv.Schema({
vol.Required(CONF_ID): cv.use_variable_id(FloatOutput), vol.Required(CONF_ID): cv.use_variable_id(FloatOutput),
vol.Required(CONF_LEVEL): cv.templatable(cv.percentage), vol.Required(CONF_LEVEL): cv.templatable(cv.percentage),
}) })

View file

@ -13,7 +13,7 @@ MULTI_CONF = True
PCA9685OutputComponent = output.output_ns.class_('PCA9685OutputComponent', PCA9685OutputComponent = output.output_ns.class_('PCA9685OutputComponent',
Component, i2c.I2CDevice) Component, i2c.I2CDevice)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(PCA9685OutputComponent), cv.GenerateID(): cv.declare_variable_id(PCA9685OutputComponent),
vol.Required(CONF_FREQUENCY): vol.All(cv.frequency, vol.Required(CONF_FREQUENCY): vol.All(cv.frequency,
vol.Range(min=23.84, max=1525.88)), vol.Range(min=23.84, max=1525.88)),

View file

@ -20,7 +20,7 @@ PCF8675_GPIO_MODES = {
PCF8574GPIOInputPin = io_ns.class_('PCF8574GPIOInputPin', GPIOInputPin) PCF8574GPIOInputPin = io_ns.class_('PCF8574GPIOInputPin', GPIOInputPin)
PCF8574GPIOOutputPin = io_ns.class_('PCF8574GPIOOutputPin', GPIOOutputPin) PCF8574GPIOOutputPin = io_ns.class_('PCF8574GPIOOutputPin', GPIOOutputPin)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.declare_variable_id(pins.PCF8574Component), vol.Required(CONF_ID): cv.declare_variable_id(pins.PCF8574Component),
vol.Optional(CONF_ADDRESS, default=0x21): cv.i2c_address, vol.Optional(CONF_ADDRESS, default=0x21): cv.i2c_address,
vol.Optional(CONF_PCF8575, default=False): cv.boolean, vol.Optional(CONF_PCF8575, default=False): cv.boolean,

View file

@ -17,7 +17,7 @@ PN532Component = binary_sensor.binary_sensor_ns.class_('PN532Component', Polling
spi.SPIDevice) spi.SPIDevice)
PN532Trigger = binary_sensor.binary_sensor_ns.class_('PN532Trigger', Trigger.template(std_string)) PN532Trigger = binary_sensor.binary_sensor_ns.class_('PN532Trigger', Trigger.template(std_string))
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(PN532Component), cv.GenerateID(): cv.declare_variable_id(PN532Component),
cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent), cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent),
vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,

View file

@ -11,7 +11,7 @@ PowerSupplyComponent = esphome_ns.class_('PowerSupplyComponent', Component)
MULTI_CONF = True MULTI_CONF = True
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.declare_variable_id(PowerSupplyComponent), vol.Required(CONF_ID): cv.declare_variable_id(PowerSupplyComponent),
vol.Required(CONF_PIN): pins.gpio_output_pin_schema, vol.Required(CONF_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_ENABLE_TIME): cv.positive_time_period_milliseconds, vol.Optional(CONF_ENABLE_TIME): cv.positive_time_period_milliseconds,

View file

@ -1,5 +1,3 @@
import voluptuous as vol
from esphome.components import binary_sensor, uart from esphome.components import binary_sensor, uart
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_UART_ID from esphome.const import CONF_ID, CONF_UART_ID
@ -12,7 +10,7 @@ DEPENDENCIES = ['uart']
RDM6300Component = binary_sensor.binary_sensor_ns.class_('RDM6300Component', Component, RDM6300Component = binary_sensor.binary_sensor_ns.class_('RDM6300Component', Component,
uart.UARTDevice) uart.UARTDevice)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(RDM6300Component), cv.GenerateID(): cv.declare_variable_id(RDM6300Component),
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(uart.UARTComponent), cv.GenerateID(CONF_UART_ID): cv.use_variable_id(uart.UARTComponent),
}).extend(cv.COMPONENT_SCHEMA.schema) }).extend(cv.COMPONENT_SCHEMA.schema)

View file

@ -40,7 +40,7 @@ def validate_dumpers_all(value):
raise vol.Invalid("Not valid dumpers") raise vol.Invalid("Not valid dumpers")
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(RemoteReceiverComponent), cv.GenerateID(): cv.declare_variable_id(RemoteReceiverComponent),
vol.Required(CONF_PIN): pins.gpio_input_pin_schema, vol.Required(CONF_PIN): pins.gpio_input_pin_schema,
vol.Optional(CONF_DUMP, default=[]): vol.Optional(CONF_DUMP, default=[]):

View file

@ -39,7 +39,7 @@ RC_SWITCH_TIMING_SCHEMA = vol.All([cv.uint8_t], vol.Length(min=2, max=2))
RC_SWITCH_PROTOCOL_SCHEMA = vol.Any( RC_SWITCH_PROTOCOL_SCHEMA = vol.Any(
vol.All(vol.Coerce(int), vol.Range(min=1, max=7)), vol.All(vol.Coerce(int), vol.Range(min=1, max=7)),
vol.Schema({ cv.Schema({
vol.Required(CONF_PULSE_LENGTH): cv.uint32_t, vol.Required(CONF_PULSE_LENGTH): cv.uint32_t,
vol.Optional(CONF_SYNC, default=[1, 31]): RC_SWITCH_TIMING_SCHEMA, vol.Optional(CONF_SYNC, default=[1, 31]): RC_SWITCH_TIMING_SCHEMA,
vol.Optional(CONF_ZERO, default=[1, 3]): RC_SWITCH_TIMING_SCHEMA, vol.Optional(CONF_ZERO, default=[1, 3]): RC_SWITCH_TIMING_SCHEMA,
@ -48,23 +48,23 @@ RC_SWITCH_PROTOCOL_SCHEMA = vol.Any(
}) })
) )
RC_SWITCH_RAW_SCHEMA = vol.Schema({ RC_SWITCH_RAW_SCHEMA = cv.Schema({
vol.Required(CONF_CODE): validate_rc_switch_code, vol.Required(CONF_CODE): validate_rc_switch_code,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA, vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
}) })
RC_SWITCH_TYPE_A_SCHEMA = vol.Schema({ RC_SWITCH_TYPE_A_SCHEMA = cv.Schema({
vol.Required(CONF_GROUP): vol.All(validate_rc_switch_code, vol.Length(min=5, max=5)), vol.Required(CONF_GROUP): vol.All(validate_rc_switch_code, vol.Length(min=5, max=5)),
vol.Required(CONF_DEVICE): vol.All(validate_rc_switch_code, vol.Length(min=5, max=5)), vol.Required(CONF_DEVICE): vol.All(validate_rc_switch_code, vol.Length(min=5, max=5)),
vol.Required(CONF_STATE): cv.boolean, vol.Required(CONF_STATE): cv.boolean,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA, vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
}) })
RC_SWITCH_TYPE_B_SCHEMA = vol.Schema({ RC_SWITCH_TYPE_B_SCHEMA = cv.Schema({
vol.Required(CONF_ADDRESS): vol.All(cv.uint8_t, vol.Range(min=1, max=4)), vol.Required(CONF_ADDRESS): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
vol.Required(CONF_CHANNEL): vol.All(cv.uint8_t, vol.Range(min=1, max=4)), vol.Required(CONF_CHANNEL): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
vol.Required(CONF_STATE): cv.boolean, vol.Required(CONF_STATE): cv.boolean,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA, vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
}) })
RC_SWITCH_TYPE_C_SCHEMA = vol.Schema({ RC_SWITCH_TYPE_C_SCHEMA = cv.Schema({
vol.Required(CONF_FAMILY): cv.one_of('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', vol.Required(CONF_FAMILY): cv.one_of('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', lower=True), 'l', 'm', 'n', 'o', 'p', lower=True),
vol.Required(CONF_GROUP): vol.All(cv.uint8_t, vol.Range(min=1, max=4)), vol.Required(CONF_GROUP): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
@ -72,14 +72,14 @@ RC_SWITCH_TYPE_C_SCHEMA = vol.Schema({
vol.Required(CONF_STATE): cv.boolean, vol.Required(CONF_STATE): cv.boolean,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA, vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
}) })
RC_SWITCH_TYPE_D_SCHEMA = vol.Schema({ RC_SWITCH_TYPE_D_SCHEMA = cv.Schema({
vol.Required(CONF_GROUP): cv.one_of('a', 'b', 'c', 'd', lower=True), vol.Required(CONF_GROUP): cv.one_of('a', 'b', 'c', 'd', lower=True),
vol.Required(CONF_DEVICE): vol.All(cv.uint8_t, vol.Range(min=1, max=3)), vol.Required(CONF_DEVICE): vol.All(cv.uint8_t, vol.Range(min=1, max=3)),
vol.Required(CONF_STATE): cv.boolean, vol.Required(CONF_STATE): cv.boolean,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA, vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
}) })
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(RemoteTransmitterComponent), cv.GenerateID(): cv.declare_variable_id(RemoteTransmitterComponent),
vol.Required(CONF_PIN): pins.gpio_output_pin_schema, vol.Required(CONF_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_CARRIER_DUTY_PERCENT): vol.All(cv.percentage_int, vol.Optional(CONF_CARRIER_DUTY_PERCENT): vol.All(cv.percentage_int,

View file

@ -44,12 +44,12 @@ FILTERS_SCHEMA = cv.ensure_list({
vol.Optional(CONF_MULTIPLY): cv.float_, vol.Optional(CONF_MULTIPLY): cv.float_,
vol.Optional(CONF_FILTER_OUT): cv.float_, vol.Optional(CONF_FILTER_OUT): cv.float_,
vol.Optional(CONF_FILTER_NAN): None, vol.Optional(CONF_FILTER_NAN): None,
vol.Optional(CONF_SLIDING_WINDOW_MOVING_AVERAGE): vol.All(vol.Schema({ vol.Optional(CONF_SLIDING_WINDOW_MOVING_AVERAGE): vol.All(cv.Schema({
vol.Optional(CONF_WINDOW_SIZE, default=15): cv.positive_not_null_int, vol.Optional(CONF_WINDOW_SIZE, default=15): cv.positive_not_null_int,
vol.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int, vol.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int,
vol.Optional(CONF_SEND_FIRST_AT): cv.positive_not_null_int, vol.Optional(CONF_SEND_FIRST_AT): cv.positive_not_null_int,
}), validate_send_first_at), }), validate_send_first_at),
vol.Optional(CONF_EXPONENTIAL_MOVING_AVERAGE): vol.Schema({ vol.Optional(CONF_EXPONENTIAL_MOVING_AVERAGE): cv.Schema({
vol.Optional(CONF_ALPHA, default=0.1): cv.positive_float, vol.Optional(CONF_ALPHA, default=0.1): cv.positive_float,
vol.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int, vol.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int,
}), }),

View file

@ -64,7 +64,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME680GasResistanceSensor), cv.GenerateID(): cv.declare_variable_id(BME680GasResistanceSensor),
})), })),
vol.Optional(CONF_IIR_FILTER): cv.one_of(*IIR_FILTER_OPTIONS, upper=True), vol.Optional(CONF_IIR_FILTER): cv.one_of(*IIR_FILTER_OPTIONS, upper=True),
vol.Optional(CONF_HEATER): vol.Any(None, vol.All(vol.Schema({ vol.Optional(CONF_HEATER): vol.Any(None, vol.All(cv.Schema({
vol.Optional(CONF_TEMPERATURE, default=320): vol.All(vol.Coerce(int), vol.Range(200, 400)), vol.Optional(CONF_TEMPERATURE, default=320): vol.All(vol.Coerce(int), vol.Range(200, 400)),
vol.Optional(CONF_DURATION, default='150ms'): vol.All( vol.Optional(CONF_DURATION, default='150ms'): vol.All(
cv.positive_time_period_milliseconds, vol.Range(max=core.TimePeriod(milliseconds=4032))) cv.positive_time_period_milliseconds, vol.Range(max=core.TimePeriod(milliseconds=4032)))

View file

@ -24,7 +24,7 @@ INA3221PowerSensor = sensor.sensor_ns.class_('INA3221PowerSensor', sensor.EmptyP
SENSOR_KEYS = [CONF_BUS_VOLTAGE, CONF_SHUNT_VOLTAGE, CONF_CURRENT, CONF_POWER] SENSOR_KEYS = [CONF_BUS_VOLTAGE, CONF_SHUNT_VOLTAGE, CONF_CURRENT, CONF_POWER]
INA3221_CHANNEL_SCHEMA = vol.All(vol.Schema({ INA3221_CHANNEL_SCHEMA = vol.All(cv.Schema({
vol.Optional(CONF_BUS_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA.extend({ vol.Optional(CONF_BUS_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA3221VoltageSensor), cv.GenerateID(): cv.declare_variable_id(INA3221VoltageSensor),
})), })),

View file

@ -41,7 +41,7 @@ def validate_internal_filter(value):
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(PulseCounterSensorComponent), cv.GenerateID(): cv.declare_variable_id(PulseCounterSensorComponent),
vol.Required(CONF_PIN): pins.internal_gpio_input_pin_schema, vol.Required(CONF_PIN): pins.internal_gpio_input_pin_schema,
vol.Optional(CONF_COUNT_MODE): vol.Schema({ vol.Optional(CONF_COUNT_MODE): cv.Schema({
vol.Required(CONF_RISING_EDGE): COUNT_MODE_SCHEMA, vol.Required(CONF_RISING_EDGE): COUNT_MODE_SCHEMA,
vol.Required(CONF_FALLING_EDGE): COUNT_MODE_SCHEMA, vol.Required(CONF_FALLING_EDGE): COUNT_MODE_SCHEMA,
}), }),

View file

@ -35,7 +35,7 @@ def to_code(config):
BUILD_FLAGS = '-DUSE_TEMPLATE_SENSOR' BUILD_FLAGS = '-DUSE_TEMPLATE_SENSOR'
CONF_SENSOR_TEMPLATE_PUBLISH = 'sensor.template.publish' CONF_SENSOR_TEMPLATE_PUBLISH = 'sensor.template.publish'
SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({ SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.use_variable_id(sensor.Sensor), vol.Required(CONF_ID): cv.use_variable_id(sensor.Sensor),
vol.Required(CONF_STATE): cv.templatable(cv.float_), vol.Required(CONF_STATE): cv.templatable(cv.float_),
}) })

View file

@ -12,7 +12,7 @@ SPIComponent = esphome_ns.class_('SPIComponent', Component)
SPIDevice = esphome_ns.class_('SPIDevice') SPIDevice = esphome_ns.class_('SPIDevice')
MULTI_CONF = True MULTI_CONF = True
CONFIG_SCHEMA = vol.All(vol.Schema({ CONFIG_SCHEMA = vol.All(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(SPIComponent), cv.GenerateID(): cv.declare_variable_id(SPIComponent),
vol.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema, vol.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_MISO_PIN): pins.gpio_input_pin_schema, vol.Optional(CONF_MISO_PIN): pins.gpio_input_pin_schema,

View file

@ -8,7 +8,7 @@ from esphome.cpp_types import App, Component, esphome_ns
StatusLEDComponent = esphome_ns.class_('StatusLEDComponent', Component) StatusLEDComponent = esphome_ns.class_('StatusLEDComponent', Component)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(StatusLEDComponent), cv.GenerateID(): cv.declare_variable_id(StatusLEDComponent),
vol.Optional(CONF_PIN): pins.gpio_output_pin_schema, vol.Optional(CONF_PIN): pins.gpio_output_pin_schema,
}).extend(cv.COMPONENT_SCHEMA.schema) }).extend(cv.COMPONENT_SCHEMA.schema)

View file

@ -60,7 +60,7 @@ def validate_speed(value):
return value return value
STEPPER_SCHEMA = vol.Schema({ STEPPER_SCHEMA = cv.Schema({
vol.Required(CONF_MAX_SPEED): validate_speed, vol.Required(CONF_MAX_SPEED): validate_speed,
vol.Optional(CONF_ACCELERATION): validate_acceleration, vol.Optional(CONF_ACCELERATION): validate_acceleration,
vol.Optional(CONF_DECELERATION): validate_acceleration, vol.Optional(CONF_DECELERATION): validate_acceleration,
@ -85,7 +85,7 @@ def setup_stepper(stepper_var, config):
BUILD_FLAGS = '-DUSE_STEPPER' BUILD_FLAGS = '-DUSE_STEPPER'
CONF_STEPPER_SET_TARGET = 'stepper.set_target' CONF_STEPPER_SET_TARGET = 'stepper.set_target'
STEPPER_SET_TARGET_ACTION_SCHEMA = vol.Schema({ STEPPER_SET_TARGET_ACTION_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.use_variable_id(Stepper), vol.Required(CONF_ID): cv.use_variable_id(Stepper),
vol.Required(CONF_TARGET): cv.templatable(cv.int_), vol.Required(CONF_TARGET): cv.templatable(cv.int_),
}) })
@ -105,7 +105,7 @@ def stepper_set_target_to_code(config, action_id, arg_type, template_arg):
CONF_STEPPER_REPORT_POSITION = 'stepper.report_position' CONF_STEPPER_REPORT_POSITION = 'stepper.report_position'
STEPPER_REPORT_POSITION_ACTION_SCHEMA = vol.Schema({ STEPPER_REPORT_POSITION_ACTION_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.use_variable_id(Stepper), vol.Required(CONF_ID): cv.use_variable_id(Stepper),
vol.Required(CONF_POSITION): cv.templatable(cv.int_), vol.Required(CONF_POSITION): cv.templatable(cv.int_),
}) })

View file

@ -31,7 +31,7 @@ def validate_substitution_key(value):
return value return value
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
validate_substitution_key: cv.string_strict, validate_substitution_key: cv.string_strict,
}) })

View file

@ -43,7 +43,7 @@ RCSwitchTypeDTransmitter = remote_ns.class_('RCSwitchTypeDTransmitter', RCSwitch
def validate_raw(value): def validate_raw(value):
if isinstance(value, dict): if isinstance(value, dict):
return vol.Schema({ return cv.Schema({
cv.GenerateID(): cv.declare_variable_id(int32), cv.GenerateID(): cv.declare_variable_id(int32),
vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)], vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)), vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)),
@ -55,29 +55,29 @@ def validate_raw(value):
PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(RemoteTransmitter), cv.GenerateID(): cv.declare_variable_id(RemoteTransmitter),
vol.Optional(CONF_JVC): vol.Schema({ vol.Optional(CONF_JVC): cv.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t, vol.Required(CONF_DATA): cv.hex_uint32_t,
}), }),
vol.Optional(CONF_LG): vol.Schema({ vol.Optional(CONF_LG): cv.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t, vol.Required(CONF_DATA): cv.hex_uint32_t,
vol.Optional(CONF_NBITS, default=28): cv.one_of(28, 32, int=True), vol.Optional(CONF_NBITS, default=28): cv.one_of(28, 32, int=True),
}), }),
vol.Optional(CONF_NEC): vol.Schema({ vol.Optional(CONF_NEC): cv.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,
}), }),
vol.Optional(CONF_SAMSUNG): vol.Schema({ vol.Optional(CONF_SAMSUNG): cv.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t, vol.Required(CONF_DATA): cv.hex_uint32_t,
}), }),
vol.Optional(CONF_SONY): vol.Schema({ vol.Optional(CONF_SONY): cv.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t, vol.Required(CONF_DATA): cv.hex_uint32_t,
vol.Optional(CONF_NBITS, default=12): cv.one_of(12, 15, 20, int=True), vol.Optional(CONF_NBITS, default=12): cv.one_of(12, 15, 20, int=True),
}), }),
vol.Optional(CONF_PANASONIC): vol.Schema({ vol.Optional(CONF_PANASONIC): cv.Schema({
vol.Required(CONF_ADDRESS): cv.hex_uint16_t, vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
vol.Required(CONF_COMMAND): cv.hex_uint32_t, vol.Required(CONF_COMMAND): cv.hex_uint32_t,
}), }),
vol.Optional(CONF_RC5): vol.Schema({ vol.Optional(CONF_RC5): cv.Schema({
vol.Required(CONF_ADDRESS): vol.All(cv.hex_int, vol.Range(min=0, max=0x1F)), vol.Required(CONF_ADDRESS): vol.All(cv.hex_int, vol.Range(min=0, max=0x1F)),
vol.Required(CONF_COMMAND): vol.All(cv.hex_int, vol.Range(min=0, max=0x3F)), vol.Required(CONF_COMMAND): vol.All(cv.hex_int, vol.Range(min=0, max=0x3F)),
}), }),
@ -88,7 +88,7 @@ PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_RC_SWITCH_TYPE_C): RC_SWITCH_TYPE_C_SCHEMA, vol.Optional(CONF_RC_SWITCH_TYPE_C): RC_SWITCH_TYPE_C_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_D): RC_SWITCH_TYPE_D_SCHEMA, vol.Optional(CONF_RC_SWITCH_TYPE_D): RC_SWITCH_TYPE_D_SCHEMA,
vol.Optional(CONF_REPEAT): vol.Any(cv.positive_not_null_int, vol.Schema({ vol.Optional(CONF_REPEAT): vol.Any(cv.positive_not_null_int, cv.Schema({
vol.Required(CONF_TIMES): cv.positive_not_null_int, vol.Required(CONF_TIMES): cv.positive_not_null_int,
vol.Required(CONF_WAIT_TIME): cv.positive_time_period_microseconds, vol.Required(CONF_WAIT_TIME): cv.positive_time_period_microseconds,
})), })),

View file

@ -55,7 +55,7 @@ def to_code(config):
BUILD_FLAGS = '-DUSE_TEMPLATE_SWITCH' BUILD_FLAGS = '-DUSE_TEMPLATE_SWITCH'
CONF_SWITCH_TEMPLATE_PUBLISH = 'switch.template.publish' CONF_SWITCH_TEMPLATE_PUBLISH = 'switch.template.publish'
SWITCH_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({ SWITCH_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.use_variable_id(switch.Switch), vol.Required(CONF_ID): cv.use_variable_id(switch.Switch),
vol.Required(CONF_STATE): cv.templatable(cv.boolean), vol.Required(CONF_STATE): cv.templatable(cv.boolean),
}) })

View file

@ -20,7 +20,7 @@ def validate_data(value):
if isinstance(value, str): if isinstance(value, str):
return value return value
if isinstance(value, list): if isinstance(value, list):
return vol.Schema([cv.hex_uint8_t])(value) return cv.Schema([cv.hex_uint8_t])(value)
raise vol.Invalid("data must either be a string wrapped in quotes or a list of bytes") raise vol.Invalid("data must either be a string wrapped in quotes or a list of bytes")

View file

@ -35,7 +35,7 @@ def to_code(config):
BUILD_FLAGS = '-DUSE_TEMPLATE_TEXT_SENSOR' BUILD_FLAGS = '-DUSE_TEMPLATE_TEXT_SENSOR'
CONF_TEXT_SENSOR_TEMPLATE_PUBLISH = 'text_sensor.template.publish' CONF_TEXT_SENSOR_TEMPLATE_PUBLISH = 'text_sensor.template.publish'
TEXT_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({ TEXT_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.use_variable_id(text_sensor.TextSensor), vol.Required(CONF_ID): cv.use_variable_id(text_sensor.TextSensor),
vol.Required(CONF_STATE): cv.templatable(cv.string_strict), vol.Required(CONF_STATE): cv.templatable(cv.string_strict),
}) })

View file

@ -11,7 +11,7 @@ UARTComponent = esphome_ns.class_('UARTComponent', Component)
UARTDevice = esphome_ns.class_('UARTDevice') UARTDevice = esphome_ns.class_('UARTDevice')
MULTI_CONF = True MULTI_CONF = True
CONFIG_SCHEMA = vol.All(vol.Schema({ CONFIG_SCHEMA = vol.All(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(UARTComponent), cv.GenerateID(): cv.declare_variable_id(UARTComponent),
vol.Optional(CONF_TX_PIN): pins.output_pin, vol.Optional(CONF_TX_PIN): pins.output_pin,
vol.Optional(CONF_RX_PIN): pins.input_pin, vol.Optional(CONF_RX_PIN): pins.input_pin,

View file

@ -9,7 +9,7 @@ from esphome.cpp_types import App, Component, StoringController, esphome_ns
WebServer = esphome_ns.class_('WebServer', Component, StoringController) WebServer = esphome_ns.class_('WebServer', Component, StoringController)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(WebServer), cv.GenerateID(): cv.declare_variable_id(WebServer),
vol.Optional(CONF_PORT): cv.port, vol.Optional(CONF_PORT): cv.port,
vol.Optional(CONF_CSS_URL): cv.string, vol.Optional(CONF_CSS_URL): cv.string,

View file

@ -42,7 +42,7 @@ def validate_channel(value):
return value return value
AP_MANUAL_IP_SCHEMA = vol.Schema({ AP_MANUAL_IP_SCHEMA = cv.Schema({
vol.Required(CONF_STATIC_IP): cv.ipv4, vol.Required(CONF_STATIC_IP): cv.ipv4,
vol.Required(CONF_GATEWAY): cv.ipv4, vol.Required(CONF_GATEWAY): cv.ipv4,
vol.Required(CONF_SUBNET): cv.ipv4, vol.Required(CONF_SUBNET): cv.ipv4,
@ -53,7 +53,7 @@ STA_MANUAL_IP_SCHEMA = AP_MANUAL_IP_SCHEMA.extend({
vol.Optional(CONF_DNS2, default="1.0.0.1"): cv.ipv4, vol.Optional(CONF_DNS2, default="1.0.0.1"): cv.ipv4,
}) })
WIFI_NETWORK_BASE = vol.Schema({ WIFI_NETWORK_BASE = cv.Schema({
cv.GenerateID(): cv.declare_variable_id(WiFiAP), cv.GenerateID(): cv.declare_variable_id(WiFiAP),
vol.Optional(CONF_SSID): cv.ssid, vol.Optional(CONF_SSID): cv.ssid,
vol.Optional(CONF_PASSWORD): validate_password, vol.Optional(CONF_PASSWORD): validate_password,
@ -105,7 +105,7 @@ def validate(config):
return config return config
CONFIG_SCHEMA = vol.All(vol.Schema({ CONFIG_SCHEMA = vol.All(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(WiFiComponent), cv.GenerateID(): cv.declare_variable_id(WiFiComponent),
vol.Optional(CONF_NETWORKS): cv.ensure_list(WIFI_NETWORK_STA), vol.Optional(CONF_NETWORKS): cv.ensure_list(WIFI_NETWORK_STA),

View file

@ -19,6 +19,7 @@ from esphome.util import safe_print
from typing import List, Optional, Tuple, Union # noqa from typing import List, Optional, Tuple, Union # noqa
from esphome.core import ConfigType # noqa from esphome.core import ConfigType # noqa
from esphome.yaml_util import is_secret from esphome.yaml_util import is_secret
from esphome.voluptuous_schema import ExtraKeysInvalid
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -414,17 +415,21 @@ def humanize_error(config, validation_error):
def _format_vol_invalid(ex, config, path, domain): def _format_vol_invalid(ex, config, path, domain):
# type: (vol.Invalid, ConfigType, ConfigPath, basestring) -> unicode # type: (vol.Invalid, ConfigType, ConfigPath, basestring) -> unicode
message = u'' message = u''
if u'extra keys not allowed' in ex.error_message: try:
try: paren = ex.path[-2]
paren = ex.path[-2] except IndexError:
except IndexError: paren = domain
paren = domain
if isinstance(ex, ExtraKeysInvalid):
if ex.candidates:
message += u'[{}] is an invalid option for [{}]. Did you mean {}?'.format(
ex.path[-1], paren, u', '.join(u'[{}]'.format(x) for x in ex.candidates))
else:
message += u'[{}] is an invalid option for [{}]. Please check the indentation.'.format(
ex.path[-1], paren)
elif u'extra keys not allowed' in ex.error_message:
message += u'[{}] is an invalid option for [{}].'.format(ex.path[-1], paren) message += u'[{}] is an invalid option for [{}].'.format(ex.path[-1], paren)
elif u'required key not provided' in ex.error_message: elif u'required key not provided' in ex.error_message:
try:
paren = ex.path[-2]
except IndexError:
paren = domain
message += u"'{}' is a required option for [{}].".format(ex.path[-1], paren) message += u"'{}' is a required option for [{}].".format(ex.path[-1], paren)
else: else:
message += humanize_error(_nested_getitem(config, path), ex) message += humanize_error(_nested_getitem(config, path), ex)

View file

@ -17,11 +17,13 @@ from esphome.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY,
from esphome.core import CORE, HexInt, IPAddress, Lambda, TimePeriod, TimePeriodMicroseconds, \ from esphome.core import CORE, HexInt, IPAddress, Lambda, TimePeriod, TimePeriodMicroseconds, \
TimePeriodMilliseconds, TimePeriodSeconds TimePeriodMilliseconds, TimePeriodSeconds
from esphome.py_compat import integer_types, string_types, text_type from esphome.py_compat import integer_types, string_types, text_type
from esphome.voluptuous_schema import _Schema
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
# pylint: disable=invalid-name # pylint: disable=invalid-name
Schema = _Schema
port = vol.All(vol.Coerce(int), vol.Range(min=1, max=65535)) port = vol.All(vol.Coerce(int), vol.Range(min=1, max=65535))
float_ = vol.Coerce(float) float_ = vol.Coerce(float)
positive_float = vol.All(float_, vol.Range(min=0)) positive_float = vol.All(float_, vol.Range(min=0))
@ -203,7 +205,7 @@ def templatable(other_validators):
if isinstance(value, Lambda): if isinstance(value, Lambda):
return value return value
if isinstance(other_validators, dict): if isinstance(other_validators, dict):
return vol.Schema(other_validators)(value) return Schema(other_validators)(value)
return other_validators(value) return other_validators(value)
return validator return validator
@ -273,7 +275,7 @@ def has_at_most_one_key(*keys):
TIME_PERIOD_ERROR = "Time period {} should be format number + unit, for example 5ms, 5s, 5min, 5h" TIME_PERIOD_ERROR = "Time period {} should be format number + unit, for example 5ms, 5s, 5min, 5h"
time_period_dict = vol.All( time_period_dict = vol.All(
dict, vol.Schema({ dict, Schema({
'days': float_, 'days': float_,
'hours': float_, 'hours': float_,
'minutes': float_, 'minutes': float_,
@ -727,17 +729,17 @@ def nameable(*schemas):
return validator return validator
PLATFORM_SCHEMA = vol.Schema({ PLATFORM_SCHEMA = Schema({
vol.Required(CONF_PLATFORM): valid, vol.Required(CONF_PLATFORM): valid,
}) })
MQTT_COMPONENT_AVAILABILITY_SCHEMA = vol.Schema({ MQTT_COMPONENT_AVAILABILITY_SCHEMA = Schema({
vol.Required(CONF_TOPIC): subscribe_topic, vol.Required(CONF_TOPIC): subscribe_topic,
vol.Optional(CONF_PAYLOAD_AVAILABLE, default='online'): mqtt_payload, vol.Optional(CONF_PAYLOAD_AVAILABLE, default='online'): mqtt_payload,
vol.Optional(CONF_PAYLOAD_NOT_AVAILABLE, default='offline'): mqtt_payload, vol.Optional(CONF_PAYLOAD_NOT_AVAILABLE, default='offline'): mqtt_payload,
}) })
MQTT_COMPONENT_SCHEMA = vol.Schema({ MQTT_COMPONENT_SCHEMA = Schema({
vol.Optional(CONF_NAME): string, vol.Optional(CONF_NAME): string,
vol.Optional(CONF_RETAIN): vol.All(requires_component('mqtt'), boolean), vol.Optional(CONF_RETAIN): vol.All(requires_component('mqtt'), boolean),
vol.Optional(CONF_DISCOVERY): vol.All(requires_component('mqtt'), boolean), vol.Optional(CONF_DISCOVERY): vol.All(requires_component('mqtt'), boolean),
@ -751,6 +753,6 @@ MQTT_COMMAND_COMPONENT_SCHEMA = MQTT_COMPONENT_SCHEMA.extend({
vol.Optional(CONF_COMMAND_TOPIC): vol.All(requires_component('mqtt'), subscribe_topic), vol.Optional(CONF_COMMAND_TOPIC): vol.All(requires_component('mqtt'), subscribe_topic),
}) })
COMPONENT_SCHEMA = vol.Schema({ COMPONENT_SCHEMA = Schema({
vol.Optional(CONF_SETUP_PRIORITY): float_ vol.Optional(CONF_SETUP_PRIORITY): float_
}) })

View file

@ -87,11 +87,11 @@ def validate_commit(value):
ESPHOME_CORE_VERSION_SCHEMA = vol.Any( ESPHOME_CORE_VERSION_SCHEMA = vol.Any(
validate_simple_esphome_core_version, validate_simple_esphome_core_version,
vol.Schema({ cv.Schema({
vol.Required(CONF_LOCAL): validate_local_esphome_core_version, vol.Required(CONF_LOCAL): validate_local_esphome_core_version,
}), }),
vol.All( vol.All(
vol.Schema({ cv.Schema({
vol.Optional(CONF_REPOSITORY, default=LIBRARY_URI_REPO): cv.string, vol.Optional(CONF_REPOSITORY, default=LIBRARY_URI_REPO): cv.string,
vol.Optional(CONF_COMMIT): validate_commit, vol.Optional(CONF_COMMIT): validate_commit,
vol.Optional(CONF_BRANCH): cv.string, vol.Optional(CONF_BRANCH): cv.string,
@ -159,7 +159,7 @@ def default_build_path():
return CORE.name return CORE.name
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = cv.Schema({
vol.Required(CONF_NAME): cv.valid_name, vol.Required(CONF_NAME): cv.valid_name,
vol.Required(CONF_PLATFORM): cv.one_of('ESP8266', 'ESPRESSIF8266', 'ESP32', 'ESPRESSIF32', vol.Required(CONF_PLATFORM): cv.one_of('ESP8266', 'ESPRESSIF8266', 'ESP32', 'ESPRESSIF32',
upper=True), upper=True),
@ -168,7 +168,7 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_ARDUINO_VERSION, default='recommended'): validate_arduino_version, vol.Optional(CONF_ARDUINO_VERSION, default='recommended'): validate_arduino_version,
vol.Optional(CONF_USE_CUSTOM_CODE, default=False): cv.boolean, vol.Optional(CONF_USE_CUSTOM_CODE, default=False): cv.boolean,
vol.Optional(CONF_BUILD_PATH, default=default_build_path): cv.string, vol.Optional(CONF_BUILD_PATH, default=default_build_path): cv.string,
vol.Optional(CONF_PLATFORMIO_OPTIONS): vol.Schema({ vol.Optional(CONF_PLATFORMIO_OPTIONS): cv.Schema({
cv.string_strict: vol.Any([cv.string], cv.string), cv.string_strict: vol.Any([cv.string], cv.string),
}), }),
vol.Optional(CONF_ESP8266_RESTORE_FROM_FLASH): vol.All(cv.only_on_esp8266, cv.boolean), vol.Optional(CONF_ESP8266_RESTORE_FROM_FLASH): vol.All(cv.only_on_esp8266, cv.boolean),

View file

@ -320,13 +320,13 @@ def pin_mode(value):
raise NotImplementedError raise NotImplementedError
GPIO_FULL_OUTPUT_PIN_SCHEMA = vol.Schema({ GPIO_FULL_OUTPUT_PIN_SCHEMA = cv.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_FULL_INPUT_PIN_SCHEMA = vol.Schema({ GPIO_FULL_INPUT_PIN_SCHEMA = cv.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,
@ -351,7 +351,7 @@ def shorthand_input_pullup_pin(value):
I2CDevice = esphome_ns.class_('I2CDevice') I2CDevice = esphome_ns.class_('I2CDevice')
PCF8574Component = io_ns.class_('PCF8574Component', Component, I2CDevice) PCF8574Component = io_ns.class_('PCF8574Component', Component, I2CDevice)
PCF8574_OUTPUT_PIN_SCHEMA = vol.Schema({ PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema({
vol.Required(CONF_PCF8574): cv.use_variable_id(PCF8574Component), vol.Required(CONF_PCF8574): cv.use_variable_id(PCF8574Component),
vol.Required(CONF_NUMBER): vol.Coerce(int), vol.Required(CONF_NUMBER): vol.Coerce(int),
vol.Optional(CONF_MODE): cv.one_of("OUTPUT", upper=True), vol.Optional(CONF_MODE): cv.one_of("OUTPUT", upper=True),

View file

@ -0,0 +1,161 @@
import difflib
import itertools
import voluptuous as vol
from esphome.py_compat import string_types
class ExtraKeysInvalid(vol.Invalid):
def __init__(self, *arg, **kwargs):
self.candidates = kwargs.pop('candidates')
vol.Invalid.__init__(self, *arg, **kwargs)
# pylint: disable=protected-access, unidiomatic-typecheck
class _Schema(vol.Schema):
"""Custom cv.Schema that prints similar keys on error."""
def _compile_mapping(self, schema, invalid_msg=None):
invalid_msg = invalid_msg or 'mapping value'
# Keys that may be required
all_required_keys = set(key for key in schema
if key is not vol.Extra and
((self.required and not isinstance(key, (vol.Optional, vol.Remove)))
or isinstance(key, vol.Required)))
# Keys that may have defaults
all_default_keys = set(key for key in schema
if isinstance(key, (vol.Required, vol.Optional)))
_compiled_schema = {}
for skey, svalue in vol.iteritems(schema):
new_key = self._compile(skey)
new_value = self._compile(svalue)
_compiled_schema[skey] = (new_key, new_value)
candidates = list(vol.schema_builder._iterate_mapping_candidates(_compiled_schema))
# After we have the list of candidates in the correct order, we want to apply some
# optimization so that each
# key in the data being validated will be matched against the relevant schema keys only.
# No point in matching against different keys
additional_candidates = []
candidates_by_key = {}
for skey, (ckey, cvalue) in candidates:
if type(skey) in vol.primitive_types:
candidates_by_key.setdefault(skey, []).append((skey, (ckey, cvalue)))
elif isinstance(skey, vol.Marker) and type(skey.schema) in vol.primitive_types:
candidates_by_key.setdefault(skey.schema, []).append((skey, (ckey, cvalue)))
else:
# These are wildcards such as 'int', 'str', 'Remove' and others which should be
# applied to all keys
additional_candidates.append((skey, (ckey, cvalue)))
key_names = []
for skey in schema:
if isinstance(skey, string_types):
key_names.append(skey)
elif isinstance(skey, vol.Marker) and isinstance(skey.schema, string_types):
key_names.append(skey.schema)
def validate_mapping(path, iterable, out):
required_keys = all_required_keys.copy()
# Build a map of all provided key-value pairs.
# The type(out) is used to retain ordering in case a ordered
# map type is provided as input.
key_value_map = type(out)()
for key, value in iterable:
key_value_map[key] = value
# Insert default values for non-existing keys.
for key in all_default_keys:
if not isinstance(key.default, vol.Undefined) and \
key.schema not in key_value_map:
# A default value has been specified for this missing
# key, insert it.
key_value_map[key.schema] = key.default()
error = None
errors = []
for key, value in key_value_map.items():
key_path = path + [key]
remove_key = False
# Optimization. Validate against the matching key first, then fallback to the rest
relevant_candidates = itertools.chain(candidates_by_key.get(key, []),
additional_candidates)
# compare each given key/value against all compiled key/values
# schema key, (compiled key, compiled value)
for skey, (ckey, cvalue) in relevant_candidates:
try:
new_key = ckey(key_path, key)
except vol.Invalid as e:
if len(e.path) > len(key_path):
raise
if not error or len(e.path) > len(error.path):
error = e
continue
# Backtracking is not performed once a key is selected, so if
# the value is invalid we immediately throw an exception.
exception_errors = []
# check if the key is marked for removal
is_remove = new_key is vol.Remove
try:
cval = cvalue(key_path, value)
# include if it's not marked for removal
if not is_remove:
out[new_key] = cval
else:
remove_key = True
continue
except vol.MultipleInvalid as e:
exception_errors.extend(e.errors)
except vol.Invalid as e:
exception_errors.append(e)
if exception_errors:
if is_remove or remove_key:
continue
for err in exception_errors:
if len(err.path) <= len(key_path):
err.error_type = invalid_msg
errors.append(err)
# If there is a validation error for a required
# key, this means that the key was provided.
# Discard the required key so it does not
# create an additional, noisy exception.
required_keys.discard(skey)
break
# Key and value okay, mark as found in case it was
# a Required() field.
required_keys.discard(skey)
break
else:
if remove_key:
# remove key
continue
elif self.extra == vol.ALLOW_EXTRA:
out[key] = value
elif self.extra != vol.REMOVE_EXTRA:
if isinstance(key, string_types) and key_names:
matches = difflib.get_close_matches(key, key_names)
errors.append(ExtraKeysInvalid('extra keys not allowed', key_path,
candidates=matches))
else:
errors.append(vol.Invalid('extra keys not allowed', key_path))
# for any required keys left that weren't found and don't have defaults:
for key in required_keys:
msg = key.msg if hasattr(key, 'msg') and key.msg else 'required key not provided'
errors.append(vol.RequiredFieldInvalid(msg, path + [key]))
if errors:
raise vol.MultipleInvalid(errors)
return out
return validate_mapping