Add action to update light state without turning on

I’ve noticed a few threads where people want to change the brightness of a light but not turn it on.
This is particularly useful if you have a group of lights, some are on, and you only want to dim the ones that are currently on.

Looking at the code, the crux of the issue is that the light service only supports turn_on turn_off and toggle. Could we add an action config_change that takes all the parameters of toggle. It would function exactly the same as toggle does, but not change the on/off state.

I’m willing to have a go at raising a PR for this myself if people thing it’s a viable suggestion.

Edit: Seems like this has been suggested before. If you want this, vote / comment here: Add `light.adjust` service call · Discussion #537 · home-assistant/architecture · GitHub

Another use case is when you have dimmers or lights that could be turned on/off by a wall switch or anything outside Home Assistant and want to have different settings based on the time of the day or something else.
I’d like to be able to set the lights to certain brightness and if someone turns it on with the wall switch, it will follow the settings previously defined by Home Assistant.

How to handle if the lights doesn’t support changing settings while turned off? I mean, any risk to have a hardware (or firmware) limitation preventing this to work?

Good point!

My basic plan is simply to ignore calls when the light is off. i.e. it will NOT make it so the switched-off light “remembers” the brightness setting. That would require chaging every single light implementation :frowning:

My understanding is that the ability to adjust a light’s brightness or other property, without turning it on, is determined by the physical light’s firmware.

For example, LIFX lights have the ability and that’s why there’s a special lifx.set_state service call. To my knowledge, it’s the only light integration that supports the feature.

Philips Hue bulbs don’t support it so the Hue integration doesn’t have an equivalent set_state service call.

Right - and the fancy way to deal with this would be to pass the call down to the hardware and let it handle it if it can, but that means a lot of changes to the light entity API.

The simple way to handle this, which is what I’m proposing, is basicallly:

    async def async_handle_update_service(
        light: LightEntity, call: ServiceCall
    ) -> None:
        """Handle updating a light."""
        if light.is_on:
            await async_handle_light_on_service(light, call)
        else:
            # Obviously this has it's limitations, but works for all hardware
            pass

This doesn’t require any changes.

1 Like

Have raised a sketch PR to outline what I’m proposing: Light reload service by Gaff · Pull Request #78686 · home-assistant/core · GitHub

I’m sure there’s lots of reasons why this won’t actually work, but I figured it’s worth asking!

1 Like

I believe that if you want to add/modify one of Home Assistant’s services, you should discuss it here (to get approval):

Yeah - I just learned that!

Turns out I’m not the first person to have this idea: Add `light.adjust` service call · Discussion #537 · home-assistant/architecture · GitHub - so I’ve put some notes there.

If you want this solved then please do vote or comment on that issue :slight_smile:

Frenck’s comment says what I said; you can’t make a device do something its firmware doesn’t support.

Most lighting technologies don’t support it so there’s no compelling reason to create a lighting service call that won’t work with the majority of light integrations.

So there’s two ways of doing this feature:

  1. Send the adjust brightness command to the light only if the light is on.
  2. Send the adjust brightness command to the light, but if the light is off the light should save the brightness until it’s on.

The first one is easy and can obviously be implemented for any light. The second one is much harder, and not supported by many light platforms.

I’m only really suggesting we implement the first solution here! (It is theoretically possible to emulate the 2nd solution by storing the state in home assisant, but it’s likely to be riddled with edge cases and hard to make work in practice).

Maybe I’m misunderstanding what you are attempting to create but this is already achievable, and commonly done, with the light.turn_on service call and a template.

Example

Increase brightness by 10% for all lights that are currently on.

  - service: light.turn_on
    target:
      entity_id: >
        {{ states.light | selectattr('state', 'eq', 'on')
          | map(attribute='entity_id') | list }}
    data:
      brightness_step_pct: 10

Sure there’s a bunch of workarounds to this issue. Though I confess I’m not familiar with that one. Can you do the same for lights within a group? How does it work for a lovelace card that expects entity to be a string?

Still let’s be honest, this workaround is far from obvious! The point of changing the light service is to remove the need for such workarounds.

You may call it a “workaround” but templating a service call’s options, notably entity_id, is a very common practice and there are countless examples of it throughout the forum.

Reference: Templating

With a template one can select entities based on numerous properties. For example, only the lights that are on in the kitchen area that are based on the Hue integration and capable of changing color temperature.

Right - but if the Lovelace Light Card only accepts a single Entity ID this is never going to work?

That card is designed to control a single light or light-group entity. It has never provided more flexibility than that largely because standard cards don’t support templating (the Markdown card is an exception) although some custom cards do.

Currently, rotating the card’s slider performs two functions: turn on the light and set its brightness. How do you propose to use it to set a light’s brightness without turning on the light?

My plan is to attach it to a group of lights. Right now if some of those lights are on and I adjust the brightness using the card, it willl switch on all the lights (and set the brightness). I want it to adjust the brightness only of the lights in the group that are already on.

Doesn’t seem too crazy a thing to ask for, right?

Maybe not crazy but definitely a Breaking Change from the card’s current behavior which always acts on all group members (which is governed by the group entity as opposed to the card).