} else: conf = { CONF_TYPE: TYPE_GIT, CONF_URL: f"https://github.com/{m.group(1)}/{m.group(2)}.git", } if m.group(3): conf[CONF_REF] = m.group(3) return SOURCE_SCHEMA(conf) SOURCE_SCHEMA = cv.Any( validate_source_shorthand, cv.typed_schema({ TYPE_GIT: cv.Schema(GIT_SCHEMA), TYPE_LOCAL: cv.Schema(LOCAL_SCHEMA), }), ) CONFIG_SCHEMA = cv.ensure_list({ cv.Required(CONF_SOURCE): SOURCE_SCHEMA, cv.Optional(CONF_REFRESH, default="1d"): cv.All(cv.string, cv.source_refresh), cv.Optional(CONF_COMPONENTS, default="all"): cv.Any("all", cv.ensure_list(cv.string)), }) async def to_code(config):
WAKEUP_CAUSES_SCHEMA = cv.Schema({ cv.Required(CONF_DEFAULT): cv.positive_time_period_milliseconds, cv.Optional(CONF_TOUCH_WAKEUP_REASON): cv.positive_time_period_milliseconds, cv.Optional(CONF_GPIO_WAKEUP_REASON): cv.positive_time_period_milliseconds, }) CONFIG_SCHEMA = cv.Schema({ cv.GenerateID(): cv.declare_id(DeepSleepComponent), cv.Optional(CONF_RUN_DURATION): cv.Any( cv.All(cv.only_on_esp32, WAKEUP_CAUSES_SCHEMA), cv.positive_time_period_milliseconds, ), cv.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds, cv.Optional(CONF_WAKEUP_PIN): cv.All(cv.only_on_esp32, pins.internal_gpio_input_pin_schema, validate_pin_number), cv.Optional(CONF_WAKEUP_PIN_MODE): cv.All(cv.only_on_esp32, cv.enum(WAKEUP_PIN_MODES), upper=True), cv.Optional(CONF_ESP32_EXT1_WAKEUP): cv.All( cv.only_on_esp32, cv.Schema({ cv.Required(CONF_PINS): cv.ensure_list(pins.internal_gpio_input_pin_schema, validate_pin_number),
extraflame_ns = cg.esphome_ns.namespace("extraflame") ExtraflameHub = extraflame_ns.class_("ExtraflameHub", cg.Component, uart.UARTDevice) ExtraflameComponent = extraflame_ns.class_("ExtraflameComponent", cg.PollingComponent) ExtraflameWriteAction = extraflame_ns.class_("ExtraflameWriteAction", Action) ExtraflameDumpAction = extraflame_ns.class_("ExtraflameDumpAction", Action) ExtraflameDumpFinishTrigger = extraflame_ns.class_( "ExtraflameDumpFinishTrigger", Trigger.template(cg.std_string)) ExtraflameIsDumpingCondition = extraflame_ns.class_( "ExtraflameIsDumpingCondition", Condition) is_memory_address = cv.Any( cv.one_of(*MEMORY_ADDRESSES, upper=True), cv.All( cv.hex_int, cv.one_of(*[v for k, v in MEMORY_ADDRESSES.items()], int=True), ), ) EXTRAFLAME_COMPONENT_SCHEMA = cv.polling_component_schema("60s").extend({ cv.GenerateID(CONF_EXTRAFLAME_ID): cv.use_id(ExtraflameHub), cv.Required(CONF_ADDRESS): cv.hex_uint8_t, cv.Required(CONF_MEMORY): is_memory_address, }) CONFIG_SCHEMA = (cv.Schema({ cv.GenerateID(): cv.declare_id(ExtraflameHub),
def validate_none_(value): if value in ("none", "None"): return None if cv.boolean(value) is False: return None raise cv.Invalid("Must be none") CONFIG_SCHEMA = cv.Schema( { cv.GenerateID(): cv.declare_id(ESP32ImprovComponent), cv.GenerateID(CONF_BLE_SERVER_ID): cv.use_id(esp32_ble_server.BLEServer), cv.Required(CONF_AUTHORIZER): cv.Any( validate_none_, cv.use_id(binary_sensor.BinarySensor) ), cv.Optional(CONF_STATUS_INDICATOR): cv.use_id(output.BinaryOutput), cv.Optional( CONF_IDENTIFY_DURATION, default="10s" ): cv.positive_time_period_milliseconds, cv.Optional( CONF_AUTHORIZED_DURATION, default="1min" ): cv.positive_time_period_milliseconds, } ).extend(cv.COMPONENT_SCHEMA) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config)
cv.GenerateID(CONF_PRESET_ID): cv.declare_id(Preset), }) PRESET_SCHEMA = cv.Any( PRESET_SCHEMA_BASE.extend({cv.Required(CONF_EFFECT): cv.string}), PRESET_SCHEMA_BASE.extend({ cv.Required(CONF_COLOR_TEMPERATURE): cv.color_temperature, cv.Optional(CONF_BRIGHTNESS): cv.percentage, cv.Optional(CONF_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, }), PRESET_SCHEMA_BASE.extend({ cv.Required(CONF_RED): cv.percentage, cv.Required(CONF_GREEN): cv.percentage, cv.Required(CONF_BLUE): cv.percentage, cv.Optional(CONF_BRIGHTNESS): cv.percentage, cv.Optional(CONF_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, }), ) CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({ cv.GenerateID(CONF_ID): cv.declare_id(XiaomiBslamp2LightState),
import esphome.config_validation as cv 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:
NONADDRESSABLE_SEGMENT_SCHEMA = cv.COMPONENT_SCHEMA.extend({ cv.Required(CONF_SINGLE_LIGHT_ID): cv.use_id(light.LightState), cv.GenerateID(CONF_ADDRESSABLE_LIGHT_ID): cv.declare_id(AddressableLightWrapper), cv.GenerateID(CONF_LIGHT_ID): cv.declare_id(light.types.LightState), }) 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.Any(ADDRESSABLE_SEGMENT_SCHEMA, NONADDRESSABLE_SEGMENT_SCHEMA), validate_from_to, ), cv.Length(min=1), ), }) FINAL_VALIDATE_SCHEMA = cv.Schema( { cv.Required(CONF_SEGMENTS): [validate_segment], }, extra=cv.ALLOW_EXTRA, ) async def to_code(config):
CONFIG_SCHEMA = cv.Schema({ cv.Required(CONF_NAME): cv.valid_name, cv.Required(CONF_PLATFORM): cv.one_of('ESP8266', 'ESP32', upper=True), cv.Required(CONF_BOARD): validate_board, cv.Optional(CONF_COMMENT): cv.string, cv.Optional(CONF_ARDUINO_VERSION, default='recommended'): validate_arduino_version, cv.Optional(CONF_BUILD_PATH, default=default_build_path): cv.string, cv.Optional(CONF_PLATFORMIO_OPTIONS, default={}): cv.Schema({ cv.string_strict: cv.Any([cv.string], cv.string), }), cv.SplitDefault(CONF_ESP8266_RESTORE_FROM_FLASH, esp8266=False): cv.All(cv.only_on_esp8266, cv.boolean), cv.SplitDefault(CONF_BOARD_FLASH_MODE, esp8266='dout'): cv.one_of(*BUILD_FLASH_MODES, lower=True), cv.Optional(CONF_ON_BOOT): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StartupTrigger), cv.Optional(CONF_PRIORITY, default=600.0): cv.float_, }), cv.Optional(CONF_ON_SHUTDOWN): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID):
ICON_GAS_CYLINDER, 1, DEVICE_CLASS_EMPTY, STATE_CLASS_MEASUREMENT, ), cv.Optional(CONF_IIR_FILTER, default="OFF"): cv.enum(IIR_FILTER_OPTIONS, upper=True), cv.Optional(CONF_HEATER): cv.Any( None, cv.All( cv.Schema({ cv.Optional(CONF_TEMPERATURE, default=320): cv.int_range(min=200, max=400), cv.Optional(CONF_DURATION, default="150ms"): cv.All( cv.positive_time_period_milliseconds, cv.Range(max=core.TimePeriod(milliseconds=4032)), ), }), cv.has_at_least_one_key(CONF_TEMPERATURE, CONF_DURATION), ), ), }).extend(cv.polling_component_schema("60s")).extend( i2c.i2c_device_schema(0x76))) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await i2c.register_i2c_device(var, config)
req.raise_for_status() except requests.exceptions.RequestException as e: raise cv.Invalid( f"Could not download ttf file for {name} ({ttf_url}): {e}") path.parent.mkdir(exist_ok=True, parents=True) path.write_bytes(req.content) return value GFONTS_SCHEMA = cv.All( { cv.Required(CONF_FAMILY): cv.string_strict, cv.Optional(CONF_WEIGHT, default="regular"): cv.Any(cv.int_, validate_weight_name), cv.Optional(CONF_ITALIC, default=False): cv.boolean, }, download_gfonts, ) def validate_file_shorthand(value): value = cv.string_strict(value) if value.startswith("gfonts://"): match = re.match(r"^gfonts://([^@]+)(@.+)?$", value) if match is None: raise cv.Invalid( "Could not parse gfonts shorthand syntax, please check it") family = match.group(1)
analog_threshold_ns = cg.esphome_ns.namespace("analog_threshold") AnalogThresholdBinarySensor = analog_threshold_ns.class_( "AnalogThresholdBinarySensor", binary_sensor.BinarySensor, cg.Component ) CONF_UPPER = "upper" CONF_LOWER = "lower" CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend( { cv.GenerateID(): cv.declare_id(AnalogThresholdBinarySensor), cv.Required(CONF_SENSOR_ID): cv.use_id(sensor.Sensor), cv.Required(CONF_THRESHOLD): cv.Any( cv.float_, cv.Schema( {cv.Required(CONF_UPPER): cv.float_, cv.Required(CONF_LOWER): cv.float_} ), ), } ).extend(cv.COMPONENT_SCHEMA) async def to_code(config): var = await binary_sensor.new_binary_sensor(config) await cg.register_component(var, config) sens = await cg.get_variable(config[CONF_SENSOR_ID]) cg.add(var.set_sensor(sens)) if isinstance(config[CONF_THRESHOLD], float): cg.add(var.set_upper_threshold(config[CONF_THRESHOLD]))
cv.Length(min=1), ), cv.Optional(CONF_REF): cv.git_ref, cv.Optional(CONF_REFRESH, default="1d"): cv.All( cv.string, cv.source_refresh ), } ), cv.has_at_least_one_key(CONF_FILE, CONF_FILES), ) CONFIG_SCHEMA = cv.All( cv.Schema( { str: cv.Any(validate_source_shorthand, BASE_SCHEMA, dict), } ), validate_git_package, ) def _process_base_package(config: dict) -> dict: repo_dir = git.clone_or_update( url=config[CONF_URL], ref=config.get(CONF_REF), refresh=config[CONF_REFRESH], domain=DOMAIN, username=config.get(CONF_USERNAME), password=config.get(CONF_PASSWORD), )
def validate_none_(value): if value in ("none", "None"): return None if cv.boolean(value) is False: return None raise cv.Invalid("Must be none") CONFIG_SCHEMA = cv.Schema({ cv.GenerateID(): cv.declare_id(ESP32ImprovComponent), cv.GenerateID(CONF_BLE_SERVER_ID): cv.use_id(esp32_ble_server.BLEServer), cv.Required(CONF_AUTHORIZER): cv.Any(validate_none_, cv.use_id(binary_sensor.BinarySensor)), cv.Optional(CONF_STATUS_INDICATOR): cv.use_id(output.BinaryOutput), cv.Optional(CONF_IDENTIFY_DURATION, default="10s"): cv.positive_time_period_milliseconds, cv.Optional(CONF_AUTHORIZED_DURATION, default="1min"): cv.positive_time_period_milliseconds, }).extend(cv.COMPONENT_SCHEMA) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) ble_server = await cg.get_variable(config[CONF_BLE_SERVER_ID]) cg.add(ble_server.register_service_component(var))
cv.Optional(CONF_ACCURACY_DECIMALS): validate_accuracy_decimals, cv.Optional(CONF_DEVICE_CLASS): validate_device_class, cv.Optional(CONF_STATE_CLASS): validate_state_class, cv.Optional("last_reset_type"): cv.invalid( "last_reset_type has been removed since 2021.9.0. state_class: total_increasing should be used for total values." ), cv.Optional(CONF_FORCE_UPDATE, default=False): cv.boolean, cv.Optional(CONF_EXPIRE_AFTER): cv.All( cv.requires_component("mqtt"), cv.Any(None, cv.positive_time_period_milliseconds), ), cv.Optional(CONF_FILTERS): validate_filters, cv.Optional(CONF_ON_VALUE): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(SensorStateTrigger), }), cv.Optional(CONF_ON_RAW_VALUE): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(SensorRawStateTrigger), }), cv.Optional(CONF_ON_VALUE_RANGE): automation.validate_automation(
CONF_TOUCH_WAKEUP_REASON = "touch_wakeup_reason" CONF_UNTIL = "until" WAKEUP_CAUSES_SCHEMA = cv.Schema( { cv.Required(CONF_DEFAULT): cv.positive_time_period_milliseconds, cv.Optional(CONF_TOUCH_WAKEUP_REASON): cv.positive_time_period_milliseconds, cv.Optional(CONF_GPIO_WAKEUP_REASON): cv.positive_time_period_milliseconds, } ) CONFIG_SCHEMA = cv.Schema( { cv.GenerateID(): cv.declare_id(DeepSleepComponent), cv.Optional(CONF_RUN_DURATION): cv.Any( cv.All(cv.only_on_esp32, WAKEUP_CAUSES_SCHEMA), cv.positive_time_period_milliseconds, ), cv.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds, cv.Optional(CONF_WAKEUP_PIN): cv.All( cv.only_on_esp32, pins.internal_gpio_input_pin_schema, validate_pin_number ), cv.Optional(CONF_WAKEUP_PIN_MODE): cv.All( cv.only_on_esp32, cv.enum(WAKEUP_PIN_MODES), upper=True ), cv.Optional(CONF_ESP32_EXT1_WAKEUP): cv.All( cv.only_on_esp32, cv.Schema( { cv.Required(CONF_PINS): cv.ensure_list( pins.internal_gpio_input_pin_schema, validate_pin_number ),
if this_negative == last_negative: 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_)))
HTTP_REQUEST_GET_ACTION_SCHEMA = automation.maybe_conf( CONF_URL, HTTP_REQUEST_ACTION_SCHEMA.extend( { cv.Optional(CONF_METHOD, default="GET"): cv.one_of("GET", upper=True), } ), ) HTTP_REQUEST_POST_ACTION_SCHEMA = automation.maybe_conf( CONF_URL, HTTP_REQUEST_ACTION_SCHEMA.extend( { cv.Optional(CONF_METHOD, default="POST"): cv.one_of("POST", upper=True), cv.Exclusive(CONF_BODY, "body"): cv.templatable(cv.string), cv.Exclusive(CONF_JSON, "body"): cv.Any( cv.lambda_, cv.All(cv.Schema({cv.string: cv.templatable(cv.string_strict)})), ), } ), ) HTTP_REQUEST_SEND_ACTION_SCHEMA = HTTP_REQUEST_ACTION_SCHEMA.extend( { cv.Required(CONF_METHOD): cv.one_of( "GET", "POST", "PUT", "DELETE", "PATCH", upper=True ), cv.Exclusive(CONF_BODY, "body"): cv.templatable(cv.string), cv.Exclusive(CONF_JSON, "body"): cv.Any( cv.lambda_, cv.All(cv.Schema({cv.string: cv.templatable(cv.string_strict)})), ), }
HTTP_REQUEST_GET_ACTION_SCHEMA = automation.maybe_conf( CONF_URL, HTTP_REQUEST_ACTION_SCHEMA.extend({ cv.Optional(CONF_METHOD, default='GET'): cv.one_of('GET', upper=True), })) HTTP_REQUEST_POST_ACTION_SCHEMA = automation.maybe_conf( CONF_URL, HTTP_REQUEST_ACTION_SCHEMA.extend({ cv.Optional(CONF_METHOD, default='POST'): cv.one_of('POST', upper=True), cv.Exclusive(CONF_BODY, 'body'): cv.templatable(cv.string), cv.Exclusive(CONF_JSON, 'body'): cv.Any( cv.lambda_, cv.All(cv.Schema({cv.string: cv.templatable(cv.string_strict)})), ), })) HTTP_REQUEST_SEND_ACTION_SCHEMA = HTTP_REQUEST_ACTION_SCHEMA.extend({ cv.Required(CONF_METHOD): cv.one_of('GET', 'POST', 'PUT', 'DELETE', 'PATCH', upper=True), cv.Exclusive(CONF_BODY, 'body'): cv.templatable(cv.string), cv.Exclusive(CONF_JSON, 'body'): cv.Any( cv.lambda_, cv.All(cv.Schema({cv.string: cv.templatable(cv.string_strict)})), ), })
cg.add(var.set_disco_state(False)) yield var @automation.register_action("preset.activate", ActivatePresetAction, cv.Schema( maybe_simple_preset_action( cv.Any( cv.Schema({ cv.GenerateID(CONF_PRESETS_ID): cv.use_id(PresetsContainer), cv.Required(CONF_GROUP): is_preset_group, cv.Optional(CONF_PRESET): is_preset }), cv.Schema({ cv.GenerateID(CONF_PRESETS_ID): cv.use_id(PresetsContainer), cv.Required(CONF_NEXT): cv.one_of(CONF_GROUP, CONF_PRESET, lower=True) }))))) def preset_activate_to_code(config, action_id, template_arg, args): presets_var = yield cg.get_variable(config[CONF_PRESETS_ID]) action_var = cg.new_Pvariable(action_id, template_arg, presets_var) if CONF_NEXT in config: cg.add(action_var.set_operation(f"next_{config[CONF_NEXT]}")) elif CONF_PRESET in config: cg.add(action_var.set_operation("activate_preset"))
DEPENDENCIES = ['network'] AUTO_LOAD = ['json'] def validate_message_just_topic(value): value = cv.publish_topic(value) return MQTT_MESSAGE_BASE({CONF_TOPIC: value}) MQTT_MESSAGE_BASE = cv.Schema({ cv.Required(CONF_TOPIC): cv.publish_topic, cv.Optional(CONF_QOS, default=0): cv.mqtt_qos, cv.Optional(CONF_RETAIN, default=True): cv.boolean, }) MQTT_MESSAGE_TEMPLATE_SCHEMA = cv.Any(None, MQTT_MESSAGE_BASE, validate_message_just_topic) MQTT_MESSAGE_SCHEMA = cv.Any(None, MQTT_MESSAGE_BASE.extend({ cv.Required(CONF_PAYLOAD): cv.mqtt_payload, })) mqtt_ns = cg.esphome_ns.namespace('mqtt') MQTTMessage = mqtt_ns.struct('MQTTMessage') MQTTClientComponent = mqtt_ns.class_('MQTTClientComponent', cg.Component) MQTTPublishAction = mqtt_ns.class_('MQTTPublishAction', automation.Action) MQTTPublishJsonAction = mqtt_ns.class_('MQTTPublishJsonAction', automation.Action) MQTTMessageTrigger = mqtt_ns.class_('MQTTMessageTrigger', automation.Trigger.template(cg.std_string), cg.Component) MQTTJsonMessageTrigger = mqtt_ns.class_('MQTTJsonMessageTrigger', automation.Trigger.template(cg.JsonObjectConstRef))
return SOURCE_SCHEMA(conf) def validate_refresh(value: str): if value.lower() == "always": return validate_refresh("0s") if value.lower() == "never": return validate_refresh("1000y") return cv.positive_time_period_seconds(value) SOURCE_SCHEMA = cv.Any( validate_source_shorthand, cv.typed_schema( { TYPE_GIT: cv.Schema(GIT_SCHEMA), TYPE_LOCAL: cv.Schema(LOCAL_SCHEMA), } ), ) CONFIG_SCHEMA = cv.ensure_list( { cv.Required(CONF_SOURCE): SOURCE_SCHEMA, cv.Optional(CONF_REFRESH, default="1d"): cv.All(cv.string, validate_refresh), cv.Optional(CONF_COMPONENTS, default="all"): cv.Any( "all", cv.ensure_list(cv.string) ), } )