mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 10:12:52 +00:00
[adc] Skip the output raw, sample count, attenuation and sampling mode setters when they match the defaults (#20068)
This commit is contained in:
@@ -128,10 +128,10 @@ class ADCSensor final : public sensor::Sensor, public PollingComponent, public v
|
||||
#endif // USE_RP2
|
||||
|
||||
protected:
|
||||
uint8_t sample_count_{1};
|
||||
bool output_raw_{false};
|
||||
uint8_t sample_count_{1}; // Must match DEFAULT_SAMPLES in sensor.py
|
||||
bool output_raw_{false}; // Must match CONF_RAW default in sensor.py
|
||||
InternalGPIOPin *pin_;
|
||||
SamplingMode sampling_mode_{SamplingMode::AVG};
|
||||
SamplingMode sampling_mode_{SamplingMode::AVG}; // Must match DEFAULT_SAMPLING_MODE in sensor.py
|
||||
|
||||
#ifdef USE_ESP32
|
||||
float sample_autorange_();
|
||||
@@ -139,7 +139,7 @@ class ADCSensor final : public sensor::Sensor, public PollingComponent, public v
|
||||
bool autorange_{false};
|
||||
adc_oneshot_unit_handle_t adc_handle_{nullptr};
|
||||
adc_cali_handle_t calibration_handle_{nullptr};
|
||||
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
|
||||
adc_atten_t attenuation_{ADC_ATTEN_DB_0}; // Must match DEFAULT_ATTENUATION in sensor.py
|
||||
adc_channel_t channel_{};
|
||||
adc_unit_t adc_unit_{};
|
||||
struct SetupFlags {
|
||||
|
||||
@@ -48,6 +48,11 @@ AUTO_LOAD = ["voltage_sampler"]
|
||||
CONF_SAMPLES = "samples"
|
||||
CONF_SAMPLING_MODE = "sampling_mode"
|
||||
|
||||
# Keep in sync with the initializers in adc_sensor.h
|
||||
DEFAULT_ATTENUATION = "0db"
|
||||
DEFAULT_SAMPLING_MODE = "avg"
|
||||
DEFAULT_SAMPLES = 1
|
||||
|
||||
|
||||
_attenuation = cv.enum(ATTENUATION_MODES, lower=True)
|
||||
_sampling_mode = cv.enum(SAMPLING_MODES, lower=True)
|
||||
@@ -65,7 +70,10 @@ def validate_config(config: ConfigType) -> ConfigType:
|
||||
):
|
||||
raise cv.Invalid("ESP32-S31 only supports 'attenuation: 0db'")
|
||||
|
||||
if config.get(CONF_ATTENUATION, None) == "auto" and config.get(CONF_SAMPLES, 1) > 1:
|
||||
if (
|
||||
config.get(CONF_ATTENUATION, None) == "auto"
|
||||
and config.get(CONF_SAMPLES, DEFAULT_SAMPLES) > 1
|
||||
):
|
||||
raise cv.Invalid(
|
||||
"Automatic attenuation cannot be used when multisampling is set"
|
||||
)
|
||||
@@ -113,12 +121,16 @@ CONFIG_SCHEMA = cv.All(
|
||||
{
|
||||
cv.Required(CONF_PIN): validate_adc_pin,
|
||||
cv.Optional(CONF_RAW, default=False): cv.boolean,
|
||||
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
||||
cv.SplitDefault(CONF_ATTENUATION, esp32=DEFAULT_ATTENUATION): cv.All(
|
||||
cv.only_on_esp32, _attenuation
|
||||
),
|
||||
cv.OnlyWith(CONF_NRF_SAADC, PLATFORM_NRF52): cv.declare_id(adc_dt_spec),
|
||||
cv.Optional(CONF_SAMPLES, default=1): cv.int_range(min=1, max=255),
|
||||
cv.Optional(CONF_SAMPLING_MODE, default="avg"): _sampling_mode,
|
||||
cv.Optional(CONF_SAMPLES, default=DEFAULT_SAMPLES): cv.int_range(
|
||||
min=1, max=255
|
||||
),
|
||||
cv.Optional(
|
||||
CONF_SAMPLING_MODE, default=DEFAULT_SAMPLING_MODE
|
||||
): _sampling_mode,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s")),
|
||||
@@ -155,9 +167,13 @@ async def to_code(config: ConfigType) -> None:
|
||||
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
||||
cg.add(var.set_pin(pin))
|
||||
|
||||
cg.add(var.set_output_raw(config[CONF_RAW]))
|
||||
cg.add(var.set_sample_count(config[CONF_SAMPLES]))
|
||||
cg.add(var.set_sampling_mode(config[CONF_SAMPLING_MODE]))
|
||||
# Skip the setters when the config matches the C++ initializers.
|
||||
if config[CONF_RAW]:
|
||||
cg.add(var.set_output_raw(True))
|
||||
if (samples := config[CONF_SAMPLES]) != DEFAULT_SAMPLES:
|
||||
cg.add(var.set_sample_count(samples))
|
||||
if (sampling_mode := config[CONF_SAMPLING_MODE]) != DEFAULT_SAMPLING_MODE:
|
||||
cg.add(var.set_sampling_mode(sampling_mode))
|
||||
|
||||
if CORE.is_esp32:
|
||||
# Re-enable ESP-IDF's ADC driver (excluded by default to save compile time)
|
||||
@@ -166,7 +182,7 @@ async def to_code(config: ConfigType) -> None:
|
||||
if attenuation := config.get(CONF_ATTENUATION):
|
||||
if attenuation == "auto":
|
||||
cg.add(var.set_autorange(cg.global_ns.true))
|
||||
else:
|
||||
elif attenuation != DEFAULT_ATTENUATION:
|
||||
cg.add(var.set_attenuation(attenuation))
|
||||
|
||||
variant = get_esp32_variant()
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
esphome:
|
||||
name: test
|
||||
|
||||
esp32:
|
||||
board: esp32dev
|
||||
|
||||
sensor:
|
||||
- platform: adc
|
||||
pin: GPIO36
|
||||
name: ADC Defaults
|
||||
id: adc_defaults
|
||||
|
||||
- platform: adc
|
||||
pin: GPIO39
|
||||
name: ADC Custom
|
||||
id: adc_custom
|
||||
raw: true
|
||||
attenuation: 6db
|
||||
sampling_mode: max
|
||||
samples: 4
|
||||
@@ -30,3 +30,19 @@ def test_adc_regular_pin_is_not_deprecated(
|
||||
|
||||
assert "adc_voltage->set_is_temperature();" not in main_cpp
|
||||
assert caplog.text.count("`pin: TEMPERATURE` is deprecated") == 1
|
||||
|
||||
|
||||
def test_adc_default_setters_are_not_emitted(
|
||||
generate_main: Callable[[str | Path], str],
|
||||
) -> None:
|
||||
"""Raw, attenuation and sampling mode matching the C++ initializers are skipped."""
|
||||
main_cpp = generate_main("tests/component_tests/adc/test_adc_defaults.yaml")
|
||||
|
||||
assert "adc_defaults->set_output_raw(" not in main_cpp
|
||||
assert "adc_defaults->set_attenuation(" not in main_cpp
|
||||
assert "adc_defaults->set_sampling_mode(" not in main_cpp
|
||||
assert "adc_defaults->set_sample_count(" not in main_cpp
|
||||
assert "adc_custom->set_output_raw(true);" in main_cpp
|
||||
assert "adc_custom->set_attenuation(ADC_ATTEN_DB_6);" in main_cpp
|
||||
assert "adc_custom->set_sampling_mode(adc::SamplingMode::MAX);" in main_cpp
|
||||
assert "adc_custom->set_sample_count(4);" in main_cpp
|
||||
|
||||
Reference in New Issue
Block a user