-
-
Notifications
You must be signed in to change notification settings - Fork 29
Description
Describe the problem you have/What new integration you would like
ESPHome's current light component lacks the capability for smooth, continuous dimming control, similar to the "hold-and-release" functionality found in many commercially available smart lighting devices. This prevents users from achieving an intuitive and responsive smart lighting experience.
For reference, modern comprehensive smart home control APIs provide three different user interaction modalities for setting the dimming level of a light. Leveraging the terminology used in the Zigbee and Matter specifications, they are:
Move to Levelcommand: Specify a target dimming level and a transition time.Stepcommand: Specify an adjustment up or down in the level from the current level by a given step size over a given transition time.Move/Stopcommands: The "Move" command tells the light to begin adjusting the dimming level up or down at a particular rate. The light then increases or decreases dimming continuously until it reaches the minimum or maximum dimming level, OR it receives a "Stop" command, halting the dimming at the current level.
ESPHome already supports modalities 1 and 2 through the light.turn_on and light.dim_relative actions but it does not have explicit support for the "Move" and "Stop" commands. While it is possible to get the effect of "Move" by sending a light.turn_on action to minimum or maximum dimming level with an appropriate transition length, ESPHome does not at present have any way to properly halt in-progress dimming. A transition in progress can be halted by sending a new light.turn_on command but it will use the brightness level specified in the command or the target brightness from the original transition—not the midway point in the transition when the command is sent.
Please describe your use case for this integration and alternatives you've tried:
My primary use case is to provide an intuitive and responsive smart lighting control experience when running ESPHome on e.g. a Martin Jerry SD01 dimmer, which has a PWM light output and 3 buttons—main, up and down. When I hold the up or down button, I expect the light brightness to change smoothly and continuously, stopping precisely when I release it. This mirrors the behavior of physical dimmer switches and dedicated smart dimmers.
Currently, achieving this in ESPHome requires complex workarounds. I've attempted to use rapid-fire light.turn_on commands with short transitions, but this leads to a choppy, non-smooth dimming effect and significantly increases system overhead and network traffic, especially when integrated with Home Assistant. The lack of ability to start a continuous adjustment without a predetermined target, or to halt an ongoing transition while preserving its intermediate state, forces these suboptimal solutions. I have implemented a workaround in my ESPHome packages repo, but it uses a clunky combination of global variables, an on_loop lambda, and spamming the Light component with many turn_on calls while a dimming button is held down.
This feature would enable:
- Intuitive Control: Users could hold a button to dim up or down, releasing it at their desired brightness, matching common user expectations from commercial devices.
- Precision: Users could stop at exact desired brightness levels without being limited to predefined steps.
- Responsiveness: Local execution within ESPHome would eliminate network latency, providing immediate and smooth adjustments.
- Accessibility: Continuous adjustment is often easier for users with fine motor skill limitations compared to stepped adjustments.
Additional context
This feature is essential for aligning ESPHome with modern smart home user experience expectations and bridging the gap with capabilities already present in many smart lighting protocols and device firmwares. While Home Assistant currently lacks native, first-class support for smooth dimming, providing this capability at the ESPHome level would empower users to build superior lighting controls.
I added a similar feature to Tasmota in 2021, and it's time to add it to ESPHome. I have a longer-term goal of building support into Home Assistant to allow cross-platform smooth dimming—e.g. use the up/down buttons of Lutron Pico Remotes to enable smooth dimming of a group of Zigbee bulbs and ESPHome-powered smart dimmers. However, I want to first ensure the open source firmware ecosystem has solid on-device support.
The implementation should build upon the existing transition infrastructure within ESPHome's light component. The key missing functionalities to enable ability to provide intuitive "hold-and-release" dimming functionality are:
- The ability to initiate continuous brightness/color adjustments without predefined start and end points.
- The ability to halt ongoing transitions instantly while accurately preserving the current intermediate light state (brightness/color).
Concerns regarding complexity, resource usage, design philosophy, and maintenance burden can be addressed:
- Complexity: The feature can leverage existing transition infrastructure with minimal new code paths, and a modular design could allow optional compilation and gradual rollout.
- Resource Usage: Efficient implementation should reuse existing mechanisms, leading to negligible overhead (prototypes show minimal memory increase and CPU impact).
- Design Philosophy: This feature aligns with ESPHome's local-first approach and empowers users with advanced control from simple YAML config.
- Maintenance Burden: A clear API design and comprehensive unit tests reduce long-term support costs.
Example YAML config
esphome:
name: smooth_dimmer_device
project:
name: Martin Jerry.SD01 Smart Dimmer
version: "1"
esp8266:
board: esp01_1m
restore_from_flash: true
# Define the PWM output for the light
output:
- platform: esp32_pwm
pin: GPIO2
id: light_pwm_output
# Define the light component
light:
- platform: monochromatic
output: light_pwm_output
name: "Living Room Light"
id: living_room_light
# Define the binary sensors for dimming up and down
binary_sensor:
- platform: gpio
name: "Dim Up Button"
pin:
number: GPIO0
inverted: true
mode: INPUT_PULLUP
on_press:
# Start dimming up when the button is pressed and held, with a specified speed
- light.start_dimming:
id: living_room_light
direction: up
speed: 0.25 # Example: Change brightness by 25% per second
on_release:
# Stop dimming when the button is released
- light.stop_dimming: living_room_light
- platform: gpio
pin:
number: GPIO1
inverted: true
mode: INPUT_PULLUP
name: "Dim Down Button"
on_press:
# Start dimming down when the button is pressed and held, with a specified speed
- light.start_dimming:
id: living_room_light
direction: down
speed: 0.25
on_release:
# Stop dimming when the button is released
- light.stop_dimming: living_room_light
# Optional: Add a button for toggling the light on/off
- platform: gpio
pin:
number: GPIO15
mode: INPUT_PULLUP
name: "Light Toggle Button"
on_press:
- light.toggle: living_room_lightNote: Alternative API implementations, such as adding parameters to the light.turn_on service or using different service or parameter names, should be considered. This is just a notional example.