FloatOutput Power Scaling Fields Gated Behind USE_OUTPUT_FLOAT_POWER_SCALING
The min_power_ / max_power_ / zero_means_zero_ fields and their setters on FloatOutput are now gated behind a new USE_OUTPUT_FLOAT_POWER_SCALING build flag. The codegen turns the flag on automatically whenever a YAML config references the feature. Lambdas that call id(out).set_min_power(...) / set_max_power(...) / set_zero_means_zero(...) without any matching YAML key or action will now fail to compile with a clear static_assert pointing at the one-line YAML fix.
This is a breaking change for external components and YAML configs that drive power scaling exclusively from lambdas in ESPHome 2026.5.0 and later.
Background
PR #15998: Gate FloatOutput power scaling fields behind USE_OUTPUT_FLOAT_POWER_SCALING
min_power_, max_power_, and zero_means_zero_ cost 12 bytes per instance on every PWM channel, DAC channel, LEDC output, and dimmer-chip channel — paid by every device with any output: block, regardless of whether the user touches the feature. Inside esphome/esphome, total YAML usage of min_power / max_power / zero_means_zero is on the order of 17 lines, mostly in test fixtures. The output.set_min_power / output.set_max_power runtime actions (added in #8934) have no callers outside the action's own test fixture.
This follows the same pattern the entity base classes already use — USE_POWER_SUPPLY gates BinaryOutput::power_, and USE_ENTITY_ICON / USE_ENTITY_DEVICE_CLASS / USE_ENTITY_UNIT_OF_MEASUREMENT gate string members of EntityBase. Configs that opt in pay the cost; configs that don't get it stripped.
Measured savings
Built with the unmodified example configs from devices.esphome.io for two real ESP8266 PWM lights — neither uses min_power / max_power / zero_means_zero / scaling actions:
H801 RGBW LED Controller — 5 PWM outputs (RGB + cold-white + warm-white, the "RGBWW" light: platform):
| Metric | Baseline | PR | Δ |
|---|---|---|---|
| RAM (.bss + .data) | 30,416 B | 30,352 B | -64 B |
| Flash | 346,047 B | 345,799 B | -248 B |
sizeof(ESP8266PWM) |
40 B | 28 B | -12 B |
H802 RGBW LED Controller — 4 PWM outputs: -48 B RAM, -248 B flash, same 12 B per channel.
Per-instance .bss savings scale linearly with channel count (12 B × N). Flash savings (~248 B per binary) come from the elided multiply/subtract in set_level() and the dropped scaling-related strings/branches in dump_config().
What's Changing
USE_OUTPUT_FLOAT_POWER_SCALING is a new cg.add_define() flag that controls four things at compile time on FloatOutput:
min_power_,max_power_,zero_means_zero_member fieldsset_min_power(),set_max_power(),set_zero_means_zero()setters- The min/max/zero-means-zero math inside
FloatOutput::set_level() - The
SetMinPowerAction/SetMaxPowerActionaction templates
The Python codegen turns the flag on automatically whenever:
- A
min_power:/max_power:/zero_means_zero:key is set on anyoutput:entry, or - An
output.set_min_power/output.set_max_poweraction is registered anywhere in the config.
zero_means_zero_ now has a default initializer (it was undefined before, hidden behind an unconditional setter call driven by the schema default).
Who This Affects
You are affected only if all three of these are true:
- You do not set
min_power,max_power, orzero_means_zeroon any of your outputs in YAML, and - You do not use the
output.set_min_poweroroutput.set_max_powerautomation actions anywhere, and - You do call
id(...).set_min_power(...),id(...).set_max_power(...), orid(...).set_zero_means_zero(...)directly from alambda:.
If any of those is false, your config is unaffected and behaves exactly as before.
External hardware-driver components that ship their own C++ and call these setters from setup() or dump_config() fall in this bucket — typically inverter / charger / DC-DC bridges that auto-configure scaling per detected hardware (e.g. several of the syssi/esphome-* repos).
Migration Guide
YAML lambda users — add one line of YAML
The build will fail with a clear error at your lambda:
error: static assertion failed: set_min_power() requires USE_OUTPUT_FLOAT_POWER_SCALING.
To enable it, add 'min_power: 0%' (or any value) to one output entry in your YAML — the
codegen will then keep the scaling fields.
The fix is one line of YAML — add this to any one output entry:
output:
- platform: esp8266_pwm
id: out
pin: 4
min_power: 0% # ← add this (or max_power: 100%, or zero_means_zero: true)
min_power: 0% / max_power: 100% are the existing defaults, so this changes no runtime behavior — it just tells the codegen "compile in runtime power scaling so my lambda can use it."
External component authors — declare the define
If your component ships its own output.* C++ and depends on the scaling setters, you have two options:
-
(Recommended) Add the YAML key on any output. The codegen will turn the define on for you. This is the same flow regular users follow.
-
If you cannot rely on user YAML, declare the define in your component's Python codegen:
import esphome.codegen as cg async def to_code(config): cg.add_define("USE_OUTPUT_FLOAT_POWER_SCALING") # ...The
outputcomponent will then include the fields and setters regardless of YAML.
Finding Code That Needs Updates
# C++ — find calls to the gated setters from lambdas or component code
grep -rEn 'set_min_power|set_max_power|set_zero_means_zero' your_component/
# YAML — find lambdas that call the setters
grep -rEn 'set_min_power|set_max_power|set_zero_means_zero' your_configs/
# YAML — check if any output entry already enables the feature (no action needed if so).
# Drop ^ to also catch top-level entries; expect false positives from unrelated
# components that happen to use a same-named key — visually confirm matches are
# under an output: entry before concluding you've already opted in.
grep -rEn '(min_power|max_power|zero_means_zero):' your_configs/
Questions?
If you have questions about migrating your external component or configuration, please ask in:
- ESPHome Discord - #devs channel
- ESPHome GitHub Discussions
Related Documentation
- PR #15998 — Gate FloatOutput power scaling fields behind USE_OUTPUT_FLOAT_POWER_SCALING
- Output component documentation —
min_power/max_power/zero_means_zeroreference - Pattern reference:
USE_POWER_SUPPLY(gatesBinaryOutput::power_),USE_ENTITY_ICON/USE_ENTITY_DEVICE_CLASS/USE_ENTITY_UNIT_OF_MEASUREMENT(gateEntityBasestrings)
Comments
Feel free to leave a comment here to discuss this post wth others. You can ask questions, share your experience, or suggest improvements. If you have a question about a specific feature or issue, please consider using the ESPHome Discord. Stick to English and follow ESPHome's code of conduct. These comments exist on a discussion on GitHub, so you can also comment there directly if you prefer.