import logging from esphome.const import ( CONF_ID, CONF_INPUT, CONF_INVERTED, CONF_MODE, CONF_NUMBER, CONF_OPEN_DRAIN, CONF_OUTPUT, CONF_PULLDOWN, CONF_PULLUP, ) from esphome import pins import esphome.config_validation as cv import esphome.codegen as cg from .const import host_ns _LOGGER = logging.getLogger(__name__) HostGPIOPin = host_ns.class_("HostGPIOPin", cg.InternalGPIOPin) def _translate_pin(value): if isinstance(value, dict) or value is None: raise cv.Invalid( "This variable only supports pin numbers, not full pin schemas " "(with inverted and mode)." ) if isinstance(value, int): return value try: return int(value) except ValueError: pass if value.startswith("GPIO"): return cv.int_(value[len("GPIO") :].strip()) return value def validate_gpio_pin(value): return _translate_pin(value) HOST_PIN_SCHEMA = cv.All( { cv.GenerateID(): cv.declare_id(HostGPIOPin), cv.Required(CONF_NUMBER): validate_gpio_pin, cv.Optional(CONF_MODE, default={}): cv.Schema( { cv.Optional(CONF_INPUT, default=False): cv.boolean, cv.Optional(CONF_OUTPUT, default=False): cv.boolean, cv.Optional(CONF_OPEN_DRAIN, default=False): cv.boolean, cv.Optional(CONF_PULLUP, default=False): cv.boolean, cv.Optional(CONF_PULLDOWN, default=False): cv.boolean, } ), cv.Optional(CONF_INVERTED, default=False): cv.boolean, }, ) @pins.PIN_SCHEMA_REGISTRY.register("host", HOST_PIN_SCHEMA) async def host_pin_to_code(config): var = cg.new_Pvariable(config[CONF_ID]) num = config[CONF_NUMBER] cg.add(var.set_pin(num)) cg.add(var.set_inverted(config[CONF_INVERTED])) cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE]))) return var