raise cv.Invalid("From ({}) must not be larger than to ({})" "".format(value[CONF_FROM], value[CONF_TO])) return value CONFIG_SCHEMA = light.ADDRESSABLE_LIGHT_SCHEMA.extend({ cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(PartitionLightOutput), cv.Required(CONF_SEGMENTS): cv.All( cv.ensure_list( { cv.Required(CONF_ID): cv.use_id(light.AddressableLightState), cv.Required(CONF_FROM): cv.positive_int, cv.Required(CONF_TO): cv.positive_int, }, validate_from_to), cv.Length(min=1)), }) def to_code(config): segments = [] for conf in config[CONF_SEGMENTS]: var = yield cg.get_variable(conf[CONF_ID]) segments.append( AddressableSegment(var, conf[CONF_FROM], conf[CONF_TO] - conf[CONF_FROM] + 1)) var = cg.new_Pvariable(config[CONF_OUTPUT_ID], segments) yield cg.register_component(var, config) yield light.register_light(var, config)
SensorMapType = binary_sensor_map_ns.enum('SensorMapType') CONF_GROUP = 'group' SENSOR_MAP_TYPES = { CONF_GROUP: SensorMapType.BINARY_SENSOR_MAP_TYPE_GROUP, } entry = { cv.Required(CONF_BINARY_SENSOR): cv.use_id(binary_sensor.BinarySensor), cv.Required(CONF_VALUE): cv.float_, } CONFIG_SCHEMA = cv.typed_schema({ CONF_GROUP: sensor.sensor_schema(UNIT_EMPTY, ICON_CHECK_CIRCLE_OUTLINE, 0).extend({ cv.GenerateID(): cv.declare_id(BinarySensorMap), cv.Required(CONF_CHANNELS): cv.All(cv.ensure_list(entry), cv.Length(min=1)), }), }, lower=True) def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) yield cg.register_component(var, config) yield sensor.register_sensor(var, config) constant = SENSOR_MAP_TYPES[config[CONF_TYPE]] cg.add(var.set_sensor_type(constant)) for ch in config[CONF_CHANNELS]: input_var = yield cg.get_variable(ch[CONF_BINARY_SENSOR]) cg.add(var.add_channel(input_var, ch[CONF_VALUE]))
cv.percentage, cv.Optional(CONF_WHITE, default=1.0): cv.percentage, cv.Required(CONF_DURATION): cv.positive_time_period_milliseconds, }), cv.has_at_least_one_key( CONF_STATE, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, ), ), cv.Length(min=2), ), }, ) def strobe_effect_to_code(config, effect_id): var = cg.new_Pvariable(effect_id, config[CONF_NAME]) colors = [] for color in config.get(CONF_COLORS, []): colors.append( cg.StructInitializer( StrobeLightEffectColor, ( "color", LightColorValues( color[CONF_STATE], color[CONF_BRIGHTNESS],
entry = { cv.Required(CONF_BINARY_SENSOR): cv.use_id(binary_sensor.BinarySensor), cv.Required(CONF_VALUE): cv.float_, } CONFIG_SCHEMA = cv.typed_schema( { CONF_GROUP: sensor.sensor_schema(UNIT_EMPTY, ICON_CHECK_CIRCLE_OUTLINE, 0, DEVICE_CLASS_EMPTY).extend({ cv.GenerateID(): cv.declare_id(BinarySensorMap), cv.Required(CONF_CHANNELS): cv.All(cv.ensure_list(entry), cv.Length(min=1)), }), }, lower=True, ) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await sensor.register_sensor(var, config) constant = SENSOR_MAP_TYPES[config[CONF_TYPE]] cg.add(var.set_sensor_type(constant)) for ch in config[CONF_CHANNELS]:
await cg.register_component(var, {}) return var def validate_not_all_from_same(config): if all(conf[CONF_FROM] == config[0][CONF_FROM] for conf in config): raise cv.Invalid( "The 'from' values of the calibrate_linear filter cannot all point " "to the same value! Please add more values to the filter.") return config @FILTER_REGISTRY.register( "calibrate_linear", CalibrateLinearFilter, cv.All(cv.ensure_list(validate_datapoint), cv.Length(min=2), validate_not_all_from_same), ) async def calibrate_linear_filter_to_code(config, filter_id): x = [conf[CONF_FROM] for conf in config] y = [conf[CONF_TO] for conf in config] k, b = fit_linear(x, y) return cg.new_Pvariable(filter_id, k, b) CONF_DATAPOINTS = "datapoints" CONF_DEGREE = "degree" def validate_calibrate_polynomial(config): if config[CONF_DEGREE] >= len(config[CONF_DATAPOINTS]):
if CONF_KEYS in obj: if len(obj[CONF_KEYS]) != len(obj[CONF_ROWS]) * len(obj[CONF_COLUMNS]): raise cv.Invalid( "The number of key codes must equal the number of buttons") return obj CONFIG_SCHEMA = cv.All( cv.COMPONENT_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(Keypad), cv.Required(CONF_ROWS): cv.All( cv.ensure_list( {cv.Required(CONF_PIN): pins.gpio_output_pin_schema}), cv.Length(min=1)), cv.Required(CONF_COLUMNS): cv.All( cv.ensure_list({cv.Required(CONF_PIN): pins.gpio_input_pin_schema}), cv.Length(min=1)), cv.Optional(CONF_KEYS): cv.string, cv.Optional(CONF_DEBOUNCE_TIME, default=1): cv.int_range(min=1, max=100), cv.Optional(CONF_HAS_DIODES): cv.boolean, }), check_keys) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID])
if CONF_INITIAL_OPTION in config: if config[CONF_INITIAL_OPTION] not in config[CONF_OPTIONS]: raise cv.Invalid( f"initial_option '{config[CONF_INITIAL_OPTION]}' is not a valid option [{', '.join(config[CONF_OPTIONS])}]" ) else: config[CONF_INITIAL_OPTION] = config[CONF_OPTIONS][0] return config CONFIG_SCHEMA = cv.All( select.SELECT_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(TemplateSelect), cv.Required(CONF_OPTIONS): cv.All(cv.ensure_list(cv.string_strict), cv.Length(min=1)), cv.Optional(CONF_LAMBDA): cv.returning_lambda, cv.Optional(CONF_OPTIMISTIC): cv.boolean, cv.Optional(CONF_SET_ACTION): automation.validate_automation(single=True), cv.Optional(CONF_INITIAL_OPTION): cv.string_strict, cv.Optional(CONF_RESTORE_VALUE): cv.boolean, }).extend(cv.polling_component_schema("60s")), validate_initial_value_in_options, )
}) BRIGHTNESS_ONLY_LIGHT_SCHEMA = LIGHT_SCHEMA.extend({ cv.Optional(CONF_GAMMA_CORRECT, default=2.8): cv.positive_float, cv.Optional(CONF_DEFAULT_TRANSITION_LENGTH, default='1s'): cv.positive_time_period_milliseconds, cv.Optional(CONF_EFFECTS): validate_effects(MONOCHROMATIC_EFFECTS), }) RGB_LIGHT_SCHEMA = BRIGHTNESS_ONLY_LIGHT_SCHEMA.extend({ cv.Optional(CONF_EFFECTS): validate_effects(RGB_EFFECTS), }) ADDRESSABLE_LIGHT_SCHEMA = RGB_LIGHT_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(AddressableLightState), cv.Optional(CONF_EFFECTS): validate_effects(ADDRESSABLE_EFFECTS), cv.Optional(CONF_COLOR_CORRECT): cv.All([cv.percentage], cv.Length(min=3, max=4)), cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply), }) @coroutine def setup_light_core_(light_var, output_var, config): cg.add(light_var.set_restore_mode(config[CONF_RESTORE_MODE])) if CONF_INTERNAL in config: cg.add(light_var.set_internal(config[CONF_INTERNAL])) if CONF_DEFAULT_TRANSITION_LENGTH in config: cg.add(light_var.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH])) if CONF_GAMMA_CORRECT in config: cg.add(light_var.set_gamma_correct(config[CONF_GAMMA_CORRECT])) effects = yield cg.build_registry_list(EFFECTS_REGISTRY, config.get(CONF_EFFECTS, [])) cg.add(light_var.add_effects(effects))
last_negative = None for i, val in enumerate(value): this_negative = val < 0 if i != 0: if this_negative == last_negative: raise cv.Invalid("Values must alternate between being positive and negative, " "please see index {} and {}".format(i, i + 1), [i]) last_negative = this_negative return value RawData, RawBinarySensor, RawTrigger, RawAction, RawDumper = declare_protocol('Raw') CONF_CODE_STORAGE_ID = 'code_storage_id' RAW_SCHEMA = cv.Schema({ cv.Required(CONF_CODE): cv.All([cv.Any(cv.int_, cv.time_period_microseconds)], cv.Length(min=1), validate_raw_alternating), cv.GenerateID(CONF_CODE_STORAGE_ID): cv.declare_id(cg.int32), }) @register_binary_sensor('raw', RawBinarySensor, RAW_SCHEMA) def raw_binary_sensor(var, config): code_ = config[CONF_CODE] arr = cg.progmem_array(config[CONF_CODE_STORAGE_ID], code_) cg.add(var.set_data(arr)) cg.add(var.set_len(len(code_))) @register_trigger('raw', RawTrigger, cg.std_vector.template(cg.int32)) def raw_trigger(var, config): pass
import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import GCodeSender from esphome.const import ( CONF_ID, ) DEPENDENCIES = ["GCodeSender"] AUTO_LOAD = ["Util"] storage_ns = cg.global_ns.namespace("storage") GCodeFileReaderComponent = storage_ns.class_("GCodeFileReader", cg.Component) CONF_CANCEL_GCODES = "cancel_gcodes" CONF_GCODE_FILE_READER_ID = "gcode_file_reader_id" CONFIG_SCHEMA = (cv.Schema({ cv.GenerateID(CONF_ID): cv.declare_id(GCodeFileReaderComponent), cv.GenerateID(GCodeSender.CONF_GCODE_SENDER): cv.use_id(GCodeSender.GCodeSenderComponent), cv.Required(CONF_CANCEL_GCODES): cv.All([str], cv.Length(min=1)), }).extend(cv.COMPONENT_SCHEMA)) def to_code(config): sender = yield cg.get_variable(config[GCodeSender.CONF_GCODE_SENDER]) var = cg.new_Pvariable(config[CONF_ID], sender, config[CONF_CANCEL_GCODES]) yield cg.register_component(var, config)
@FILTER_REGISTRY.register('debounce', DebounceFilter, cv.positive_time_period_milliseconds) def debounce_filter_to_code(config, filter_id): var = cg.new_Pvariable(filter_id, config) yield cg.register_component(var, {}) yield var def validate_not_all_from_same(config): if all(conf[CONF_FROM] == config[0][CONF_FROM] for conf in config): raise cv.Invalid("The 'from' values of the calibrate_linear filter cannot all point " "to the same value! Please add more values to the filter.") return config @FILTER_REGISTRY.register('calibrate_linear', CalibrateLinearFilter, cv.All( cv.ensure_list(validate_datapoint), cv.Length(min=2), validate_not_all_from_same)) def calibrate_linear_filter_to_code(config, filter_id): x = [conf[CONF_FROM] for conf in config] y = [conf[CONF_TO] for conf in config] k, b = fit_linear(x, y) yield cg.new_Pvariable(filter_id, k, b) CONF_DATAPOINTS = 'datapoints' CONF_DEGREE = 'degree' def validate_calibrate_polynomial(config): if config[CONF_DEGREE] >= len(config[CONF_DATAPOINTS]): raise cv.Invalid("Degree is too high! Maximum possible degree with given datapoints is " "{}".format(len(config[CONF_DATAPOINTS]) - 1), [CONF_DEGREE])
CONF_MAX_FRAMERATE = "max_framerate" CONF_IDLE_FRAMERATE = "idle_framerate" CONF_JPEG_QUALITY = "jpeg_quality" CONF_VERTICAL_FLIP = "vertical_flip" CONF_HORIZONTAL_MIRROR = "horizontal_mirror" CONF_SATURATION = "saturation" CONF_TEST_PATTERN = "test_pattern" camera_range_param = cv.int_range(min=-2, max=2) CONFIG_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(ESP32Camera), cv.Required(CONF_DATA_PINS): cv.All([pins.internal_gpio_input_pin_number], cv.Length(min=8, max=8)), cv.Required(CONF_VSYNC_PIN): pins.internal_gpio_input_pin_number, cv.Required(CONF_HREF_PIN): pins.internal_gpio_input_pin_number, cv.Required(CONF_PIXEL_CLOCK_PIN): pins.internal_gpio_input_pin_number, cv.Required(CONF_EXTERNAL_CLOCK): cv.Schema({ cv.Required(CONF_PIN): pins.internal_gpio_input_pin_number, cv.Optional(CONF_FREQUENCY, default="20MHz"): cv.All(cv.frequency, cv.one_of(20e6, 10e6)), }), cv.Required(CONF_I2C_PINS): cv.Schema({
def validate_import_url(value): value = cv.string_strict(value) value = cv.Length(max=255)(value) # ignore result, only check if it's a valid shorthand validate_source_shorthand(value) return value
cv.Optional(CONF_PORT, default=80): cv.port, cv.Optional(CONF_CSS_URL, default="https://esphome.io/_static/webserver-v1.min.css"): cv.string, cv.Optional(CONF_CSS_INCLUDE): cv.file_, cv.Optional(CONF_JS_URL, default="https://esphome.io/_static/webserver-v1.min.js"): cv.string, cv.Optional(CONF_JS_INCLUDE): cv.file_, cv.Optional(CONF_AUTH): cv.Schema({ cv.Required(CONF_USERNAME): cv.All(cv.string_strict, cv.Length(min=1)), cv.Required(CONF_PASSWORD): cv.All(cv.string_strict, cv.Length(min=1)), }), cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id(web_server_base.WebServerBase), cv.Optional(CONF_INCLUDE_INTERNAL, default=False): cv.boolean, cv.Optional(CONF_OTA, default=True): cv.boolean, }, ).extend(cv.COMPONENT_SCHEMA), cv.only_with_arduino, ) @coroutine_with_priority(40.0)
CONF_MAX_FRAMERATE = 'max_framerate' CONF_IDLE_FRAMERATE = 'idle_framerate' CONF_JPEG_QUALITY = 'jpeg_quality' CONF_VERTICAL_FLIP = 'vertical_flip' CONF_HORIZONTAL_MIRROR = 'horizontal_mirror' CONF_CONTRAST = 'contrast' CONF_SATURATION = 'saturation' CONF_TEST_PATTERN = 'test_pattern' camera_range_param = cv.int_range(min=-2, max=2) CONFIG_SCHEMA = cv.Schema({ cv.GenerateID(): cv.declare_id(ESP32Camera), cv.Required(CONF_NAME): cv.string, cv.Required(CONF_DATA_PINS): cv.All([pins.input_pin], cv.Length(min=8, max=8)), cv.Required(CONF_VSYNC_PIN): pins.input_pin, cv.Required(CONF_HREF_PIN): pins.input_pin, cv.Required(CONF_PIXEL_CLOCK_PIN): pins.input_pin, cv.Required(CONF_EXTERNAL_CLOCK): cv.Schema({ cv.Required(CONF_PIN): pins.output_pin, cv.Optional(CONF_FREQUENCY, default='20MHz'): cv.All(cv.frequency, cv.one_of(20e6, 10e6)), }), cv.Required(CONF_I2C_PINS): cv.Schema({ cv.Required(CONF_SDA): pins.output_pin, cv.Required(CONF_SCL): pins.output_pin, }), cv.Optional(CONF_RESET_PIN): pins.output_pin, cv.Optional(CONF_POWER_DOWN_PIN): pins.output_pin, cv.Optional(CONF_MAX_FRAMERATE, default='10 fps'): cv.All(cv.framerate,
} CONFIG_SCHEMA = cv.typed_schema( { CONF_GROUP: sensor.sensor_schema( UNIT_EMPTY, ICON_CHECK_CIRCLE_OUTLINE, 0, DEVICE_CLASS_EMPTY, STATE_CLASS_NONE, ).extend({ cv.GenerateID(): cv.declare_id(BinarySensorMap), cv.Required(CONF_CHANNELS): cv.All(cv.ensure_list(entry), cv.Length(min=1)), }), }, lower=True, ) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await sensor.register_sensor(var, config) constant = SENSOR_MAP_TYPES[config[CONF_TYPE]] cg.add(var.set_sensor_type(constant)) for ch in config[CONF_CHANNELS]:
CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), CONF_BATTERY_REDISCHARGE_VOLTAGE: ( [0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58], "PBDV%02.1f", ), } CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( { cv.Optional(type): output.FLOAT_OUTPUT_SCHEMA.extend( { cv.Required(CONF_ID): cv.declare_id(PipsolarOutput), cv.Optional(CONF_POSSIBLE_VALUES, default=values): cv.All( cv.ensure_list(cv.positive_float), cv.Length(min=1) ), } ) for type, (values, _) in TYPES.items() } ) async def to_code(config): paren = await cg.get_variable(config[CONF_PIPSOLAR_ID]) for type, (_, command) in TYPES.items(): if type in config: conf = config[type] var = cg.new_Pvariable(conf[CONF_ID])
from esphome import automation import esphome.codegen as cg import esphome.const as ehc import esphome.config_validation as cv from esphome.core import CORE, coroutine from . import const as c from . import cpp_types as t from .service_key import create_service_key from .md5sum import get_md5sum_hexint from .payload_getter import build_payload_getter_list, validate_payload_getter_list SEND_SCHEMA = cv.Schema({ cv.Optional(c.CONF_PEERID): cv.use_id(t.Peer), cv.Optional(ehc.CONF_SERVICE): cv.All(cv.string, cv.Length(min=2)), cv.Optional(c.CONF_SERVICEKEY): create_service_key, cv.Optional(c.CONF_PAYLOADS): validate_payload_getter_list, cv.Optional(c.CONF_ON_FAIL): automation.validate_action_list, cv.Optional(c.CONF_ON_SUCCESS): automation.validate_action_list, }) @automation.register_action(c.ACTION_SEND, t.SendAction, SEND_SCHEMA) @coroutine def send_action_to_code(config, action_id, template_arg, args): component = yield cg.get_variable(CORE.config[c.CONF_WIFI_NOW][ehc.CONF_ID]) var = cg.new_Pvariable(action_id, template_arg, component) if c.CONF_PEERID in config: peer = yield cg.get_variable(config[c.CONF_PEERID]) cg.add(var.set_peer(peer)) if ehc.CONF_SERVICE in config:
def validate_not_all_from_same(config): if all(conf[CONF_FROM] == config[0][CONF_FROM] for conf in config): raise cv.Invalid( "The 'from' values of the calibrate_linear filter cannot all point " "to the same value! Please add more values to the filter." ) return config @FILTER_REGISTRY.register( "calibrate_linear", CalibrateLinearFilter, cv.All( cv.ensure_list(validate_datapoint), cv.Length(min=2), validate_not_all_from_same ), ) async def calibrate_linear_filter_to_code(config, filter_id): x = [conf[CONF_FROM] for conf in config] y = [conf[CONF_TO] for conf in config] k, b = fit_linear(x, y) return cg.new_Pvariable(filter_id, k, b) CONF_DATAPOINTS = "datapoints" CONF_DEGREE = "degree" def validate_calibrate_polynomial(config): if config[CONF_DEGREE] >= len(config[CONF_DATAPOINTS]):
CONF_IDLE_FRAMERATE = "idle_framerate" CONF_JPEG_QUALITY = "jpeg_quality" CONF_VERTICAL_FLIP = "vertical_flip" CONF_HORIZONTAL_MIRROR = "horizontal_mirror" CONF_SATURATION = "saturation" CONF_TEST_PATTERN = "test_pattern" camera_range_param = cv.int_range(min=-2, max=2) CONFIG_SCHEMA = cv.Schema({ cv.GenerateID(): cv.declare_id(ESP32Camera), cv.Required(CONF_NAME): cv.string, cv.Required(CONF_DATA_PINS): cv.All([pins.input_pin], cv.Length(min=8, max=8)), cv.Required(CONF_VSYNC_PIN): pins.input_pin, cv.Required(CONF_HREF_PIN): pins.input_pin, cv.Required(CONF_PIXEL_CLOCK_PIN): pins.input_pin, cv.Required(CONF_EXTERNAL_CLOCK): cv.Schema({ cv.Required(CONF_PIN): pins.output_pin, cv.Optional(CONF_FREQUENCY, default="20MHz"): cv.All(cv.frequency, cv.one_of(20e6, 10e6)), }), cv.Required(CONF_I2C_PINS): cv.Schema({
from esphome.components import time as time_ import esphome.config_validation as cv import esphome.codegen as cg from esphome.const import CONF_ID, CONF_SERVERS DEPENDENCIES = ['network'] sntp_ns = cg.esphome_ns.namespace('sntp') SNTPComponent = sntp_ns.class_('SNTPComponent', time_.RealTimeClock) DEFAULT_SERVERS = ["0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org"] CONFIG_SCHEMA = time_.TIME_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(SNTPComponent), cv.Optional(CONF_SERVERS, default=DEFAULT_SERVERS): cv.All(cv.ensure_list(cv.domain), cv.Length(min=1, max=3)), }).extend(cv.COMPONENT_SCHEMA) def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) servers = config[CONF_SERVERS] servers += [''] * (3 - len(servers)) cg.add(var.set_servers(*servers)) yield cg.register_component(var, config) yield time_.register_time(var, config)
cv.Optional(CONF_EFFECTS): validate_effects(MONOCHROMATIC_EFFECTS), } ) RGB_LIGHT_SCHEMA = BRIGHTNESS_ONLY_LIGHT_SCHEMA.extend( { cv.Optional(CONF_EFFECTS): validate_effects(RGB_EFFECTS), } ) ADDRESSABLE_LIGHT_SCHEMA = RGB_LIGHT_SCHEMA.extend( { cv.GenerateID(): cv.declare_id(AddressableLightState), cv.Optional(CONF_EFFECTS): validate_effects(ADDRESSABLE_EFFECTS), cv.Optional(CONF_COLOR_CORRECT): cv.All( [cv.percentage], cv.Length(min=3, max=4) ), cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply), } ) async def setup_light_core_(light_var, output_var, config): cg.add(light_var.set_restore_mode(config[CONF_RESTORE_MODE])) if CONF_INTERNAL in config: cg.add(light_var.set_internal(config[CONF_INTERNAL])) if CONF_DEFAULT_TRANSITION_LENGTH in config: cg.add( light_var.set_default_transition_length( config[CONF_DEFAULT_TRANSITION_LENGTH] )
this_negative = val < 0 if i != 0: if this_negative == last_negative: raise cv.Invalid( "Values must alternate between being positive and negative, " "please see index {} and {}".format(i, i + 1), [i]) last_negative = this_negative return value RawData, RawBinarySensor, RawTrigger, RawAction, RawDumper = declare_protocol( 'Raw') CONF_CODE_STORAGE_ID = 'code_storage_id' RAW_SCHEMA = cv.Schema({ cv.Required(CONF_CODE): cv.All([cv.Any(cv.int_, cv.time_period_microseconds)], cv.Length(min=1), validate_raw_alternating), cv.GenerateID(CONF_CODE_STORAGE_ID): cv.declare_id(cg.int32), }) @register_binary_sensor('raw', RawBinarySensor, RAW_SCHEMA) def raw_binary_sensor(var, config): code_ = config[CONF_CODE] arr = cg.progmem_array(config[CONF_ID], code_) cg.add(var.set_data(arr)) cg.add(var.set_len(len(code_))) @register_trigger('raw', RawTrigger, cg.std_vector.template(cg.int32))
var = cg.new_Pvariable(filter_id, config) yield cg.register_component(var, {}) yield var def validate_not_all_from_same(config): if all(conf[CONF_FROM] == config[0][CONF_FROM] for conf in config): raise cv.Invalid( "The 'from' values of the calibrate_linear filter cannot all point " "to the same value! Please add more values to the filter.") return config @FILTER_REGISTRY.register('calibrate_linear', CalibrateLinearFilter, cv.All(cv.ensure_list(validate_datapoint), cv.Length(min=2), validate_not_all_from_same)) def calibrate_linear_filter_to_code(config, filter_id): x = [conf[CONF_FROM] for conf in config] y = [conf[CONF_TO] for conf in config] k, b = fit_linear(x, y) yield cg.new_Pvariable(filter_id, k, b) CONF_DATAPOINTS = 'datapoints' CONF_DEGREE = 'degree' def validate_calibrate_polynomial(config): if config[CONF_DEGREE] >= len(config[CONF_DATAPOINTS]): raise cv.Invalid( "Degree is too high! Maximum possible degree with given datapoints is "
raise cv.Invalid( f"Values must alternate between being positive and negative, please see index {i} and {i + 1}", [i], ) last_negative = this_negative return value RawData, RawBinarySensor, RawTrigger, RawAction, RawDumper = declare_protocol( "Raw") CONF_CODE_STORAGE_ID = "code_storage_id" RAW_SCHEMA = cv.Schema({ cv.Required(CONF_CODE): cv.All( [cv.Any(cv.int_, cv.time_period_microseconds)], cv.Length(min=1), validate_raw_alternating, ), cv.GenerateID(CONF_CODE_STORAGE_ID): cv.declare_id(cg.int32), }) @register_binary_sensor("raw", RawBinarySensor, RAW_SCHEMA) def raw_binary_sensor(var, config): code_ = config[CONF_CODE] arr = cg.progmem_array(config[CONF_CODE_STORAGE_ID], code_) cg.add(var.set_data(arr)) cg.add(var.set_len(len(code_)))
var = cg.new_Pvariable(filter_id, config) yield cg.register_component(var, {}) yield var @FILTER_REGISTRY.register('debounce', DebounceFilter, cv.positive_time_period_milliseconds) def debounce_filter_to_code(config, filter_id): var = cg.new_Pvariable(filter_id, config) yield cg.register_component(var, {}) yield var @FILTER_REGISTRY.register('calibrate_linear', CalibrateLinearFilter, cv.All(cv.ensure_list(validate_datapoint), cv.Length(min=2))) def calibrate_linear_filter_to_code(config, filter_id): x = [conf[CONF_FROM] for conf in config] y = [conf[CONF_TO] for conf in config] k, b = fit_linear(x, y) yield cg.new_Pvariable(filter_id, k, b) CONF_DATAPOINTS = 'datapoints' CONF_DEGREE = 'degree' def validate_calibrate_polynomial(config): if config[CONF_DEGREE] >= len(config[CONF_DATAPOINTS]): raise cv.Invalid( "Degree is too high! Maximum possible degree with given datapoints is "
CONFIG_SCHEMA = cv.All( cv.Schema( { cv.GenerateID(): cv.declare_id(WebServer), cv.Optional(CONF_PORT, default=80): cv.port, cv.Optional(CONF_VERSION, default=2): cv.one_of(1, 2), cv.Optional(CONF_CSS_URL): cv.string, cv.Optional(CONF_CSS_INCLUDE): cv.file_, cv.Optional(CONF_JS_URL): cv.string, cv.Optional(CONF_JS_INCLUDE): cv.file_, cv.Optional(CONF_AUTH): cv.Schema( { cv.Required(CONF_USERNAME): cv.All( cv.string_strict, cv.Length(min=1) ), cv.Required(CONF_PASSWORD): cv.All( cv.string_strict, cv.Length(min=1) ), } ), cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id( web_server_base.WebServerBase ), cv.Optional(CONF_INCLUDE_INTERNAL, default=False): cv.boolean, cv.Optional(CONF_OTA, default=True): cv.boolean, cv.Optional(CONF_LOCAL): cv.boolean, } ).extend(cv.COMPONENT_SCHEMA), cv.only_with_arduino,
@register_effect('strobe', StrobeLightEffect, "Strobe", { cv.Optional(CONF_COLORS, default=[ {CONF_STATE: True, CONF_DURATION: '0.5s'}, {CONF_STATE: False, CONF_DURATION: '0.5s'}, ]): cv.All(cv.ensure_list(cv.Schema({ cv.Optional(CONF_STATE, default=True): cv.boolean, cv.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage, cv.Optional(CONF_RED, default=1.0): cv.percentage, cv.Optional(CONF_GREEN, default=1.0): cv.percentage, cv.Optional(CONF_BLUE, default=1.0): cv.percentage, cv.Optional(CONF_WHITE, default=1.0): cv.percentage, cv.Required(CONF_DURATION): cv.positive_time_period_milliseconds, }), cv.has_at_least_one_key(CONF_STATE, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE)), cv.Length(min=2)), }) def strobe_effect_to_code(config, effect_id): var = cg.new_Pvariable(effect_id, config[CONF_NAME]) colors = [] for color in config.get(CONF_COLORS, []): colors.append(cg.StructInitializer( StrobeLightEffectColor, ('color', LightColorValues(color[CONF_STATE], color[CONF_BRIGHTNESS], color[CONF_RED], color[CONF_GREEN], color[CONF_BLUE], color[CONF_WHITE])), ('duration', color[CONF_DURATION]), )) cg.add(var.set_colors(colors)) yield var
import esphome.const as ehc from esphome.core import coroutine, HexInt from . import const as c from . import cpp_types as t from .aes_key import create_aes_key from .md5sum import get_md5sum_hexint PEER_SCHEMA = cv.All( cv.Schema({ cv.GenerateID(): cv.declare_id(t.Peer), cv.Required(ehc.CONF_BSSID): cv.mac_address, cv.Optional(ehc.CONF_PASSWORD): cv.All(cv.string, cv.Length(min=2)), cv.Optional(c.CONF_AESKEY): create_aes_key, }), cv.has_at_most_one_key(ehc.CONF_PASSWORD, c.CONF_AESKEY)) @coroutine def peer_to_code(config): var = cg.new_Pvariable(config[ehc.CONF_ID]) cg.add(var.set_bssid([HexInt(i) for i in config[ehc.CONF_BSSID].parts])) if ehc.CONF_PASSWORD in config: cg.add(var.set_aeskey(get_md5sum_hexint(config[ehc.CONF_PASSWORD]))) if c.CONF_AESKEY in config: cg.add(var.set_aeskey(*config[c.CONF_AESKEY].as_hex_int())) yield var
import esphome.codegen as cg from esphome.core import CORE from esphome.const import CONF_ID, CONF_SERVERS DEPENDENCIES = ["network"] sntp_ns = cg.esphome_ns.namespace("sntp") SNTPComponent = sntp_ns.class_("SNTPComponent", time_.RealTimeClock) DEFAULT_SERVERS = ["0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org"] CONFIG_SCHEMA = time_.TIME_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(SNTPComponent), cv.Optional(CONF_SERVERS, default=DEFAULT_SERVERS): cv.All(cv.ensure_list(cv.Any(cv.domain, cv.hostname)), cv.Length(min=1, max=3)), }).extend(cv.COMPONENT_SCHEMA) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) servers = config[CONF_SERVERS] servers += [""] * (3 - len(servers)) cg.add(var.set_servers(*servers)) await cg.register_component(var, config) await time_.register_time(var, config) if CORE.is_esp8266 and len(servers) > 1: # We need LwIP features enabled to get 3 SNTP servers (not just one)