mirror of
https://github.com/esphome/esphome.git
synced 2024-12-23 14:04:53 +01:00
393ca64d70
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
148 lines
3.8 KiB
Python
148 lines
3.8 KiB
Python
import operator
|
|
from functools import reduce
|
|
|
|
from esphome.const import (
|
|
CONF_INPUT,
|
|
CONF_MODE,
|
|
CONF_NUMBER,
|
|
CONF_OPEN_DRAIN,
|
|
CONF_OUTPUT,
|
|
CONF_PULLDOWN,
|
|
CONF_PULLUP,
|
|
)
|
|
from esphome.util import SimpleRegistry
|
|
from esphome.core import CORE
|
|
|
|
|
|
PIN_SCHEMA_REGISTRY = SimpleRegistry()
|
|
|
|
|
|
def _set_mode(value, default_mode):
|
|
import esphome.config_validation as cv
|
|
|
|
if CONF_MODE not in value:
|
|
return {**value, CONF_MODE: default_mode}
|
|
mode = value[CONF_MODE]
|
|
if not isinstance(mode, str):
|
|
return value
|
|
# mode is a string, try parsing it like arduino pin modes
|
|
PIN_MODES = {
|
|
"INPUT": {
|
|
CONF_INPUT: True,
|
|
},
|
|
"OUTPUT": {
|
|
CONF_OUTPUT: True,
|
|
},
|
|
"INPUT_PULLUP": {
|
|
CONF_INPUT: True,
|
|
CONF_PULLUP: True,
|
|
},
|
|
"OUTPUT_OPEN_DRAIN": {
|
|
CONF_OUTPUT: True,
|
|
CONF_OPEN_DRAIN: True,
|
|
},
|
|
"INPUT_PULLDOWN_16": {
|
|
CONF_INPUT: True,
|
|
CONF_PULLDOWN: True,
|
|
},
|
|
"INPUT_PULLDOWN": {
|
|
CONF_INPUT: True,
|
|
CONF_PULLDOWN: True,
|
|
},
|
|
"INPUT_OUTPUT_OPEN_DRAIN": {
|
|
CONF_INPUT: True,
|
|
CONF_OUTPUT: True,
|
|
CONF_OPEN_DRAIN: True,
|
|
},
|
|
}
|
|
if mode.upper() not in PIN_MODES:
|
|
raise cv.Invalid(f"Unknown pin mode {mode}", [CONF_MODE])
|
|
return {**value, CONF_MODE: PIN_MODES[mode.upper()]}
|
|
|
|
|
|
def _schema_creator(default_mode, internal: bool = False):
|
|
def validator(value):
|
|
if not isinstance(value, dict):
|
|
return validator({CONF_NUMBER: value})
|
|
value = _set_mode(value, default_mode)
|
|
if not internal:
|
|
for key, entry in PIN_SCHEMA_REGISTRY.items():
|
|
if key != CORE.target_platform and key in value:
|
|
return entry[1](value)
|
|
return PIN_SCHEMA_REGISTRY[CORE.target_platform][1](value)
|
|
|
|
return validator
|
|
|
|
|
|
def _internal_number_creator(mode):
|
|
def validator(value):
|
|
value_d = {CONF_NUMBER: value}
|
|
value_d = _set_mode(value_d, mode)
|
|
return PIN_SCHEMA_REGISTRY[CORE.target_platform][1](value_d)[CONF_NUMBER]
|
|
|
|
return validator
|
|
|
|
|
|
def gpio_flags_expr(mode):
|
|
"""Convert the given mode dict to a gpio Flags expression"""
|
|
import esphome.codegen as cg
|
|
|
|
FLAGS_MAPPING = {
|
|
CONF_INPUT: cg.gpio_Flags.FLAG_INPUT,
|
|
CONF_OUTPUT: cg.gpio_Flags.FLAG_OUTPUT,
|
|
CONF_OPEN_DRAIN: cg.gpio_Flags.FLAG_OPEN_DRAIN,
|
|
CONF_PULLUP: cg.gpio_Flags.FLAG_PULLUP,
|
|
CONF_PULLDOWN: cg.gpio_Flags.FLAG_PULLDOWN,
|
|
}
|
|
active_flags = [v for k, v in FLAGS_MAPPING.items() if mode.get(k)]
|
|
if not active_flags:
|
|
return cg.gpio_Flags.FLAG_NONE
|
|
|
|
return reduce(operator.or_, active_flags)
|
|
|
|
|
|
gpio_pin_schema = _schema_creator
|
|
internal_gpio_pin_number = _internal_number_creator
|
|
gpio_output_pin_schema = _schema_creator(
|
|
{
|
|
CONF_OUTPUT: True,
|
|
}
|
|
)
|
|
gpio_input_pin_schema = _schema_creator(
|
|
{
|
|
CONF_INPUT: True,
|
|
}
|
|
)
|
|
gpio_input_pullup_pin_schema = _schema_creator(
|
|
{
|
|
CONF_INPUT: True,
|
|
CONF_PULLUP: True,
|
|
}
|
|
)
|
|
internal_gpio_output_pin_schema = _schema_creator(
|
|
{
|
|
CONF_OUTPUT: True,
|
|
},
|
|
internal=True,
|
|
)
|
|
internal_gpio_output_pin_number = _internal_number_creator({CONF_OUTPUT: True})
|
|
internal_gpio_input_pin_schema = _schema_creator(
|
|
{
|
|
CONF_INPUT: True,
|
|
},
|
|
internal=True,
|
|
)
|
|
internal_gpio_input_pin_number = _internal_number_creator({CONF_INPUT: True})
|
|
internal_gpio_input_pullup_pin_schema = _schema_creator(
|
|
{
|
|
CONF_INPUT: True,
|
|
CONF_PULLUP: True,
|
|
},
|
|
internal=True,
|
|
)
|
|
internal_gpio_input_pullup_pin_number = _internal_number_creator(
|
|
{
|
|
CONF_INPUT: True,
|
|
CONF_PULLUP: True,
|
|
}
|
|
)
|