import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import sensor, voltage_sampler from esphome.components.esp32 import get_esp32_variant from esphome.const import ( CONF_ATTENUATION, CONF_ID, CONF_NUMBER, CONF_PIN, CONF_RAW, DEVICE_CLASS_VOLTAGE, STATE_CLASS_MEASUREMENT, UNIT_VOLT, ) from esphome.core import CORE from . import ( ATTENUATION_MODES, ESP32_VARIANT_ADC1_PIN_TO_CHANNEL, validate_adc_pin, ) AUTO_LOAD = ["voltage_sampler"] def validate_config(config): if config[CONF_RAW] and config.get(CONF_ATTENUATION, None) == "auto": raise cv.Invalid("Automatic attenuation cannot be used when raw output is set.") return config adc_ns = cg.esphome_ns.namespace("adc") ADCSensor = adc_ns.class_( "ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler ) CONFIG_SCHEMA = cv.All( sensor.sensor_schema( ADCSensor, unit_of_measurement=UNIT_VOLT, accuracy_decimals=2, device_class=DEVICE_CLASS_VOLTAGE, state_class=STATE_CLASS_MEASUREMENT, ) .extend( { cv.Required(CONF_PIN): validate_adc_pin, cv.Optional(CONF_RAW, default=False): cv.boolean, cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All( cv.only_on_esp32, cv.enum(ATTENUATION_MODES, lower=True) ), } ) .extend(cv.polling_component_schema("60s")), validate_config, ) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await sensor.register_sensor(var, config) if config[CONF_PIN] == "VCC": cg.add_define("USE_ADC_SENSOR_VCC") elif config[CONF_PIN] == "TEMPERATURE": cg.add(var.set_is_temperature()) else: pin = await cg.gpio_pin_expression(config[CONF_PIN]) cg.add(var.set_pin(pin)) if CONF_RAW in config: cg.add(var.set_output_raw(config[CONF_RAW])) if CONF_ATTENUATION in config: if config[CONF_ATTENUATION] == "auto": cg.add(var.set_autorange(cg.global_ns.true)) else: cg.add(var.set_attenuation(config[CONF_ATTENUATION])) if CORE.is_esp32: variant = get_esp32_variant() pin_num = config[CONF_PIN][CONF_NUMBER] chan = ESP32_VARIANT_ADC1_PIN_TO_CHANNEL[variant][pin_num] cg.add(var.set_channel(chan))