def validate(config): if CONF_PASSWORD in config and CONF_SSID not in config: raise vol.Invalid("Cannot have WiFi password without SSID!") if CONF_SSID in config: network = {CONF_SSID: config.pop(CONF_SSID)} if CONF_PASSWORD in config: network[CONF_PASSWORD] = config.pop(CONF_PASSWORD) if CONF_NETWORKS in config: raise vol.Invalid( "You cannot use the 'ssid:' option together with 'networks:'. Please " "copy your network into the 'networks:' key") config[CONF_NETWORKS] = cv.ensure_list(WIFI_NETWORK_STA)(network) if (CONF_NETWORKS not in config) and (CONF_AP not in config): raise vol.Invalid("Please specify at least an SSID or an Access Point " "to create.") if config.get(CONF_FAST_CONNECT, False): networks = config.get(CONF_NETWORKS, []) if not networks: raise vol.Invalid( "At least one network required for fast_connect!") if len(networks) != 1: raise vol.Invalid( "Fast connect can only be used with one network!") if CONF_USE_ADDRESS not in config: if CONF_MANUAL_IP in config: use_address = str(config[CONF_MANUAL_IP][CONF_STATIC_IP]) else: use_address = CORE.name + config[CONF_DOMAIN] config[CONF_USE_ADDRESS] = use_address return config
def validate_recursive_condition(value): is_list = isinstance(value, list) value = cv.ensure_list()(value)[:] for i, item in enumerate(value): path = [i] if is_list else [] item = copy.deepcopy(item) if not isinstance(item, dict): raise vol.Invalid(u"Condition must consist of key-value mapping! Got {}".format(item), path) key = next((x for x in item if x != CONF_CONDITION_ID), None) if key is None: raise vol.Invalid(u"Key missing from action! Got {}".format(item), path) if key not in CONDITION_REGISTRY: raise vol.Invalid(u"Unable to find condition with the name '{}', is the " u"component loaded?".format(key), path + [key]) item.setdefault(CONF_CONDITION_ID, None) key2 = next((x for x in item if x not in (CONF_CONDITION_ID, key)), None) if key2 is not None: raise vol.Invalid(u"Cannot have two conditions in one item. Key '{}' overrides '{}'! " u"Did you forget to indent the block inside the condition?" u"".format(key, key2), path) validator = CONDITION_REGISTRY[key][0] try: condition = validator(item[key] or {}) except vol.Invalid as err: err.prepend(path) raise err value[i] = { CONF_CONDITION_ID: cv.declare_variable_id(Condition)(item[CONF_CONDITION_ID]), key: condition, } return value
from pi4home.components import time as time_ import pi4home.config_validation as cv from pi4home.const import CONF_ID, CONF_SERVERS from pi4home.cpp_generator import Pvariable, add from pi4home.cpp_helpers import setup_component from pi4home.cpp_types import App SNTPComponent = time_.time_ns.class_('SNTPComponent', time_.RealTimeClockComponent) PLATFORM_SCHEMA = time_.TIME_PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(SNTPComponent), vol.Optional(CONF_SERVERS): vol.All(cv.ensure_list(cv.domain), vol.Length(min=1, max=3)), }).extend(cv.COMPONENT_SCHEMA.schema) def to_code(config): rhs = App.make_sntp_component() sntp = Pvariable(config[CONF_ID], rhs) if CONF_SERVERS in config: servers = config[CONF_SERVERS] servers += [''] * (3 - len(servers)) add(sntp.set_servers(*servers)) time_.setup_time(sntp, config) setup_component(sntp, config)
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_BOARD_FLASH_MODE, default='dout'): cv.one_of(*BUILD_FLASH_MODES, lower=True), vol.Optional(CONF_ON_BOOT): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(StartupTrigger), vol.Optional(CONF_PRIORITY): cv.float_, }), vol.Optional(CONF_ON_SHUTDOWN): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ShutdownTrigger), }), vol.Optional(CONF_ON_LOOP): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(LoopTrigger), }), vol.Optional(CONF_INCLUDES): cv.ensure_list(cv.file_), vol.Optional(CONF_LIBRARIES): cv.ensure_list(cv.string_strict), vol.Optional('pi4homelib_version'): cv.invalid("The pi4homelib_version has been renamed to " "pi4home_core_version in 1.11.0"), }) def preload_core_config(config): if 'pi4homeyaml' in config: _LOGGER.warning("The pi4homeyaml section has been renamed to pi4home in 1.11.0. " "Please replace 'pi4homeyaml:' in your configuration with 'pi4home:'.") config[CONF_PI4HOME] = config.pop('pi4homeyaml') if CONF_PI4HOME not in config: raise pi4homeError(u"No pi4home section in config") core_conf = config[CONF_PI4HOME]
import voluptuous as vol from pi4home.components import output import pi4home.config_validation as cv from pi4home.const import CONF_ID, CONF_OUTPUTS, CONF_TYPE from pi4home.cpp_generator import Pvariable, get_variable from pi4home.cpp_helpers import setup_component BinaryCopyOutput = output.output_ns.class_('BinaryCopyOutput', output.BinaryOutput) FloatCopyOutput = output.output_ns.class_('FloatCopyOutput', output.FloatOutput) BINARY_SCHEMA = output.PLATFORM_SCHEMA.extend({ vol.Required(CONF_ID): cv.declare_variable_id(BinaryCopyOutput), vol.Required(CONF_TYPE): 'binary', vol.Required(CONF_OUTPUTS): cv.ensure_list(cv.use_variable_id(output.BinaryOutput)), }) FLOAT_SCHEMA = output.PLATFORM_SCHEMA.extend({ vol.Required(CONF_ID): cv.declare_variable_id(FloatCopyOutput), vol.Required(CONF_TYPE): 'float', vol.Required(CONF_OUTPUTS): cv.ensure_list(cv.use_variable_id(output.FloatOutput)), }) def validate_copy_output(value): if not isinstance(value, dict): raise vol.Invalid("Value must be dict") type = cv.string_strict(value.get(CONF_TYPE, 'float')).lower() value[CONF_TYPE] = type if type == 'binary': return BINARY_SCHEMA(value)
try: value = int(value) except ValueError: raise vol.Invalid(u"Expected integer for rotation") return cv.one_of(*DISPLAY_ROTATIONS)(value) BASIC_DISPLAY_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval, vol.Optional(CONF_LAMBDA): cv.lambda_, }) FULL_DISPLAY_PLATFORM_SCHEMA = BASIC_DISPLAY_PLATFORM_SCHEMA.extend({ vol.Optional(CONF_ROTATION): validate_rotation, vol.Optional(CONF_PAGES): vol.All(cv.ensure_list({ cv.GenerateID(): cv.declare_variable_id(DisplayPage), vol.Required(CONF_LAMBDA): cv.lambda_, }), vol.Length(min=1)), }) def setup_display_core_(display_var, config): if CONF_UPDATE_INTERVAL in config: add(display_var.set_update_interval(config[CONF_UPDATE_INTERVAL])) if CONF_ROTATION in config: add(display_var.set_rotation(DISPLAY_ROTATIONS[config[CONF_ROTATION]])) if CONF_PAGES in config: pages = [] for conf in config[CONF_PAGES]: for lambda_ in process_lambda(conf[CONF_LAMBDA], [(DisplayBufferRef, 'it')], return_type=void): yield
CustomBinaryOutputConstructor = output.output_ns.class_( 'CustomBinaryOutputConstructor') CustomFloatOutputConstructor = output.output_ns.class_( 'CustomFloatOutputConstructor') BINARY_SCHEMA = output.PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(CustomBinaryOutputConstructor), vol.Required(CONF_LAMBDA): cv.lambda_, vol.Required(CONF_TYPE): 'binary', vol.Required(CONF_OUTPUTS): cv.ensure_list( output.BINARY_OUTPUT_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(output.BinaryOutput), })), }) FLOAT_SCHEMA = output.PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(CustomFloatOutputConstructor), vol.Required(CONF_LAMBDA): cv.lambda_, vol.Required(CONF_TYPE): 'float', vol.Required(CONF_OUTPUTS): cv.ensure_list( output.FLOAT_OUTPUT_SCHEMA.extend({ cv.GenerateID():
CONFIG_SCHEMA = cv.Schema({ cv.GenerateID(): cv.declare_variable_id(DeepSleepComponent), 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, validate_pin_number), vol.Optional(CONF_WAKEUP_PIN_MODE): vol.All(cv.only_on_esp32, cv.one_of(*WAKEUP_PIN_MODES), upper=True), 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_MODE): cv.one_of(*EXT1_WAKEUP_MODES, upper=True), })), vol.Optional(CONF_RUN_DURATION): cv.positive_time_period_milliseconds, vol.Optional(CONF_RUN_CYCLES): cv.invalid("The run_cycles option has been removed in 1.11.0 as " "it was essentially the same as a run_duration of 0s." "Please use run_duration now.") }).extend(cv.COMPONENT_SCHEMA.schema) def to_code(config): rhs = App.make_deep_sleep_component() deep_sleep = Pvariable(config[CONF_ID], rhs)
import pi4home.config_validation as cv from pi4home.const import CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_SENSORS from pi4home.cpp_generator import add, process_lambda, variable from pi4home.cpp_types import std_vector CustomSensorConstructor = sensor.sensor_ns.class_('CustomSensorConstructor') PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(CustomSensorConstructor), vol.Required(CONF_LAMBDA): cv.lambda_, vol.Required(CONF_SENSORS): cv.ensure_list( sensor.SENSOR_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(sensor.Sensor), })), }) def to_code(config): for template_ in process_lambda(config[CONF_LAMBDA], [], return_type=std_vector.template( sensor.SensorPtr)): yield rhs = CustomSensorConstructor(template_) custom = variable(config[CONF_ID], rhs) for i, conf in enumerate(config[CONF_SENSORS]): rhs = custom.Pget_sensor(i)
from pi4home.components import binary_sensor import pi4home.config_validation as cv from pi4home.const import CONF_BINARY_SENSORS, CONF_ID, CONF_LAMBDA, CONF_NAME from pi4home.cpp_generator import add, process_lambda, variable from pi4home.cpp_types import std_vector CustomBinarySensorConstructor = binary_sensor.binary_sensor_ns.class_( 'CustomBinarySensorConstructor') PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(CustomBinarySensorConstructor), vol.Required(CONF_LAMBDA): cv.lambda_, vol.Required(CONF_BINARY_SENSORS): cv.ensure_list(binary_sensor.BINARY_SENSOR_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(binary_sensor.BinarySensor), })), }) def to_code(config): for template_ in process_lambda(config[CONF_LAMBDA], [], return_type=std_vector.template(binary_sensor.BinarySensorPtr)): yield rhs = CustomBinarySensorConstructor(template_) custom = variable(config[CONF_ID], rhs) for i, conf in enumerate(config[CONF_BINARY_SENSORS]): rhs = custom.Pget_binary_sensor(i) add(rhs.set_name(conf[CONF_NAME])) binary_sensor.register_binary_sensor(rhs, conf)
if CONF_USE_ADDRESS not in config: if CONF_MANUAL_IP in config: use_address = str(config[CONF_MANUAL_IP][CONF_STATIC_IP]) else: use_address = CORE.name + config[CONF_DOMAIN] config[CONF_USE_ADDRESS] = use_address return config CONFIG_SCHEMA = vol.All( cv.Schema({ cv.GenerateID(): cv.declare_variable_id(WiFiComponent), vol.Optional(CONF_NETWORKS): cv.ensure_list(WIFI_NETWORK_STA), vol.Optional(CONF_SSID): cv.ssid, vol.Optional(CONF_PASSWORD): validate_password, vol.Optional(CONF_MANUAL_IP): STA_MANUAL_IP_SCHEMA, vol.Optional(CONF_AP): WIFI_NETWORK_AP, vol.Optional(CONF_DOMAIN, default='.local'): cv.domain_name, vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds, vol.Optional(CONF_POWER_SAVE_MODE): cv.one_of(*WIFI_POWER_SAVE_MODES, upper=True), vol.Optional(CONF_FAST_CONNECT):
from pi4home.const import CONF_COMPONENTS, CONF_ID, CONF_LAMBDA from pi4home.cpp_generator import Pvariable, process_lambda, variable from pi4home.cpp_helpers import setup_component from pi4home.cpp_types import Component, ComponentPtr, pi4home_ns, std_vector CustomComponentConstructor = pi4home_ns.class_('CustomComponentConstructor') MULTI_CONF = True CONFIG_SCHEMA = cv.Schema({ cv.GenerateID(): cv.declare_variable_id(CustomComponentConstructor), vol.Required(CONF_LAMBDA): cv.lambda_, vol.Optional(CONF_COMPONENTS): cv.ensure_list( cv.Schema({ cv.GenerateID(): cv.declare_variable_id(Component) }).extend(cv.COMPONENT_SCHEMA.schema)), }) def to_code(config): for template_ in process_lambda( config[CONF_LAMBDA], [], return_type=std_vector.template(ComponentPtr)): yield rhs = CustomComponentConstructor(template_) custom = variable(config[CONF_ID], rhs) for i, comp_config in enumerate(config.get(CONF_COMPONENTS, [])): comp = Pvariable(comp_config[CONF_ID], custom.get_component(i)) setup_component(comp, comp_config)
import voluptuous as vol from pi4home.components import switch import pi4home.config_validation as cv from pi4home.const import CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_SWITCHES from pi4home.cpp_generator import add, process_lambda, variable from pi4home.cpp_types import std_vector CustomSwitchConstructor = switch.switch_ns.class_('CustomSwitchConstructor') PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(CustomSwitchConstructor), vol.Required(CONF_LAMBDA): cv.lambda_, vol.Required(CONF_SWITCHES): cv.ensure_list(switch.SWITCH_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(switch.Switch), })), }) def to_code(config): for template_ in process_lambda(config[CONF_LAMBDA], [], return_type=std_vector.template(switch.SwitchPtr)): yield rhs = CustomSwitchConstructor(template_) custom = variable(config[CONF_ID], rhs) for i, conf in enumerate(config[CONF_SWITCHES]): rhs = custom.Pget_switch(i) add(rhs.set_name(conf[CONF_NAME])) switch.register_switch(rhs, conf)
FILTERS_SCHEMA = cv.ensure_list( { vol.Optional(CONF_OFFSET): cv.float_, vol.Optional(CONF_MULTIPLY): cv.float_, vol.Optional(CONF_FILTER_OUT): cv.float_, vol.Optional('filter_nan'): cv.invalid("The filter_nan filter has been removed. Please use " "'filter_out: nan' instead"), 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_SEND_EVERY, default=15): cv.positive_not_null_int, vol.Optional(CONF_SEND_FIRST_AT): cv.positive_not_null_int, }), validate_send_first_at), vol.Optional(CONF_EXPONENTIAL_MOVING_AVERAGE): cv.Schema({ 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_CALIBRATE_LINEAR): vol.All(cv.ensure_list(validate_datapoint), vol.Length(min=2)), vol.Optional(CONF_LAMBDA): cv.lambda_, vol.Optional(CONF_THROTTLE): cv.positive_time_period_milliseconds, vol.Optional(CONF_DELTA): cv.float_, vol.Optional(CONF_UNIQUE): cv.invalid("The unique filter has been removed in 1.12, please " "replace with a delta filter with small value."), vol.Optional(CONF_HEARTBEAT): cv.positive_time_period_milliseconds, vol.Optional(CONF_DEBOUNCE): cv.positive_time_period_milliseconds, vol.Optional(CONF_OR): validate_recursive_filter, }, cv.has_exactly_one_key(*FILTER_KEYS))
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(StrobeLightEffect), vol.Optional(CONF_NAME, default="Strobe"): cv.string, vol.Optional(CONF_COLORS): vol.All( cv.ensure_list( cv.Schema({ vol.Optional(CONF_STATE, default=True): cv.boolean, vol.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage, vol.Optional(CONF_RED, default=1.0): cv.percentage, vol.Optional(CONF_GREEN, default=1.0): cv.percentage, vol.Optional(CONF_BLUE, default=1.0): cv.percentage, vol.Optional(CONF_WHITE, default=1.0): cv.percentage, vol.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)), vol.Length(min=2)), }), vol.Optional(CONF_FLICKER): cv.Schema({ cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FlickerLightEffect),
MQTT_MESSAGE_SCHEMA, vol.Optional(CONF_WILL_MESSAGE): MQTT_MESSAGE_SCHEMA, vol.Optional(CONF_SHUTDOWN_MESSAGE): MQTT_MESSAGE_SCHEMA, vol.Optional(CONF_TOPIC_PREFIX): cv.publish_topic, vol.Optional(CONF_LOG_TOPIC): vol.Any( None, MQTT_MESSAGE_BASE.extend({ vol.Optional(CONF_LEVEL): logger.is_log_level, }), validate_message_just_topic), vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266, cv.ensure_list(validate_fingerprint)), vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds, vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds, vol.Optional(CONF_ON_MESSAGE): automation.validate_automation({ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger), vol.Required(CONF_TOPIC): cv.subscribe_topic, vol.Optional(CONF_QOS): cv.mqtt_qos, vol.Optional(CONF_PAYLOAD): cv.string_strict, }),
GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_DEFAULT_OFF, 'RESTORE_DEFAULT_ON': GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_DEFAULT_ON, 'ALWAYS_OFF': GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_OFF, 'ALWAYS_ON': GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_ON, } PLATFORM_SCHEMA = cv.nameable( switch.SWITCH_PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(GPIOSwitch), vol.Required(CONF_PIN): pins.gpio_output_pin_schema, vol.Optional(CONF_RESTORE_MODE): cv.one_of(*RESTORE_MODES, upper=True, space='_'), vol.Optional(CONF_INTERLOCK): cv.ensure_list(cv.use_variable_id(switch.Switch)), }).extend(cv.COMPONENT_SCHEMA.schema)) def to_code(config): for pin in gpio_output_pin_expression(config[CONF_PIN]): yield rhs = App.make_gpio_switch(config[CONF_NAME], pin) gpio = Pvariable(config[CONF_ID], rhs) if CONF_RESTORE_MODE in config: add(gpio.set_restore_mode(RESTORE_MODES[config[CONF_RESTORE_MODE]])) if CONF_INTERLOCK in config: interlock = [] for it in config[CONF_INTERLOCK]:
Component) HeartbeatFilter = binary_sensor_ns.class_('HeartbeatFilter', Filter, Component) InvertFilter = binary_sensor_ns.class_('InvertFilter', Filter) LambdaFilter = binary_sensor_ns.class_('LambdaFilter', Filter) FILTER_KEYS = [ CONF_INVERT, CONF_DELAYED_ON, CONF_DELAYED_OFF, CONF_LAMBDA, CONF_HEARTBEAT ] FILTERS_SCHEMA = cv.ensure_list( { vol.Optional(CONF_INVERT): None, vol.Optional(CONF_DELAYED_ON): cv.positive_time_period_milliseconds, vol.Optional(CONF_DELAYED_OFF): cv.positive_time_period_milliseconds, vol.Optional(CONF_LAMBDA): cv.lambda_, vol.Optional(CONF_HEARTBEAT): cv.invalid("The heartbeat filter has been removed in 1.11.0"), }, cv.has_exactly_one_key(*FILTER_KEYS)) MULTI_CLICK_TIMING_SCHEMA = cv.Schema({ vol.Optional(CONF_STATE): cv.boolean, vol.Optional(CONF_MIN_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_MAX_LENGTH): cv.positive_time_period_milliseconds, })
return value PLATFORM_SCHEMA = cv.nameable( light.LIGHT_PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(light.AddressableLightState), cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakePartitionLight), vol.Required(CONF_SEGMENTS): vol.All( cv.ensure_list( { vol.Required(CONF_ID): cv.use_variable_id(light.AddressableLightState), vol.Required(CONF_FROM): cv.positive_int, vol.Required(CONF_TO): cv.positive_int, }, validate_from_to), vol.Length(min=1)), vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_EFFECTS): light.validate_effects(light.ADDRESSABLE_EFFECTS), })) def to_code(config): segments = [] for conf in config[CONF_SEGMENTS]: for var in get_variable(conf[CONF_ID]):
from pi4home.const import CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_TEXT_SENSORS from pi4home.cpp_generator import add, process_lambda, variable from pi4home.cpp_types import std_vector CustomTextSensorConstructor = text_sensor.text_sensor_ns.class_( 'CustomTextSensorConstructor') PLATFORM_SCHEMA = text_sensor.PLATFORM_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(CustomTextSensorConstructor), vol.Required(CONF_LAMBDA): cv.lambda_, vol.Required(CONF_TEXT_SENSORS): cv.ensure_list( text_sensor.TEXT_SENSOR_SCHEMA.extend({ cv.GenerateID(): cv.declare_variable_id(text_sensor.TextSensor), })), }) def to_code(config): for template_ in process_lambda(config[CONF_LAMBDA], [], return_type=std_vector.template( text_sensor.TextSensorPtr)): yield rhs = CustomTextSensorConstructor(template_) custom = variable(config[CONF_ID], rhs) for i, conf in enumerate(config[CONF_TEXT_SENSORS]): rhs = custom.Pget_text_sensor(i)
def validate_dumpers_all(value): if not isinstance(value, string_types): raise vol.Invalid("Not valid dumpers") if value.upper() == "ALL": return list(sorted(list(DUMPERS))) raise vol.Invalid("Not valid dumpers") CONFIG_SCHEMA = cv.Schema({ cv.GenerateID(): cv.declare_variable_id(RemoteReceiverComponent), vol.Required(CONF_PIN): vol.All(pins.internal_gpio_input_pin_schema, pins.validate_has_interrupt), vol.Optional(CONF_DUMP, default=[]): vol.Any(validate_dumpers_all, cv.ensure_list(cv.one_of(*DUMPERS, lower=True))), vol.Optional(CONF_TOLERANCE): vol.All(cv.percentage_int, vol.Range(min=0)), vol.Optional(CONF_BUFFER_SIZE): cv.validate_bytes, vol.Optional(CONF_FILTER): cv.positive_time_period_microseconds, vol.Optional(CONF_IDLE): cv.positive_time_period_microseconds, }).extend(cv.COMPONENT_SCHEMA.schema) def to_code(config): for pin in gpio_input_pin_expression(config[CONF_PIN]): yield rhs = App.make_remote_receiver_component(pin)
matches = re.findall(cfmt, value[CONF_FORMAT], flags=re.X) if len(matches) != len(value[CONF_ARGS]): raise vol.Invalid( u"Found {} printf-patterns ({}), but {} args were given!" u"".format(len(matches), u', '.join(matches), len(value[CONF_ARGS]))) return value CONF_LOGGER_LOG = 'logger.log' LOGGER_LOG_ACTION_SCHEMA = vol.All( maybe_simple_message({ vol.Required(CONF_FORMAT): cv.string, vol.Optional(CONF_ARGS, default=list): cv.ensure_list(cv.lambda_), vol.Optional(CONF_LEVEL, default="DEBUG"): cv.one_of(*LOG_LEVEL_TO_ESP_LOG, upper=True), vol.Optional(CONF_TAG, default="main"): cv.string, }), validate_printf) @ACTION_REGISTRY.register(CONF_LOGGER_LOG, LOGGER_LOG_ACTION_SCHEMA) def logger_log_action_to_code(config, action_id, template_arg, args): esp_log = LOG_LEVEL_TO_ESP_LOG[config[CONF_LEVEL]] args_ = [RawExpression(text_type(x)) for x in config[CONF_ARGS]] text = text_type( statement(esp_log(config[CONF_TAG], config[CONF_FORMAT], *args_)))