Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switching a light on at a specified light level #80

Closed
famichiki opened this issue Aug 17, 2024 · 8 comments · Fixed by #96
Closed

Switching a light on at a specified light level #80

famichiki opened this issue Aug 17, 2024 · 8 comments · Fixed by #96

Comments

@famichiki
Copy link

Is there a way to specify the light level that the light will switch on at?

For example, my light is set to 100% when it is switched off, I'd like to switch it back on again but at 50% brightness.

If I specify light_level before lamp_on it is ignored.

If I specify lamp_on then light_level, the light comes on at full brightness before quickly dimming to my specified level.

I know I could use a scene but I'd like to know if the above is possible.

@Leggin
Copy link
Owner

Leggin commented Aug 20, 2024

Hey, I think if setting light_level before lamp_on does not work, there is no way to do it. In the app it is also not possible to set the light level if the light is not on so it looks like it is not possible.

@famichiki
Copy link
Author

famichiki commented Aug 21, 2024

Do the lights accept multiple attributes being sent at once, rather than separately setting lamp_on, then light_level, then color_temperature etc? I wonder how the scenes do it.

So something like: light.set_attributes(lamp_on=True, light_level=90)

@Leggin
Copy link
Owner

Leggin commented Aug 21, 2024

Uh that is a good point, that should probably work! I will test this in the upcoming days.

@Leggin
Copy link
Owner

Leggin commented Aug 22, 2024

Sadly, it does not seem to work. So what I tried is the following with the current version of the package (you can do this as well since the dirigera_hub exposes patch()):

  1. Set the attribute field with values of isOn and lightLevel:
l = dirigera_hub.get_light_by_name("lamp1")
data = [
    {
        "attributes": {
            "lightLevel": 100,
            "isOn": False,
        }
    },
]

dirigera_hub.patch(route=f"/devices/{l.id}", data=data)

With this only the first attribute is executed, in this case the lightLevel. The isOn has no effect whatsoever on the status of the lamp. It seems when changing the order always the first attribute is executed.

  1. I used two attribute objects and sent them:
l = dirigera_hub.get_light_by_name("lamp1")
data = [
    {
        "attributes": {
            "isOn": True,
        }
    },
    {
        "attributes": {
            "lightLevel": 10,
        }
    },
]

dirigera_hub.patch(route=f"/devices/{l.id}", data=data)

In this case, the behavior is very strange.

  • When putting lightLevel first and isOn second it does not work
  • When putting isOn first and lightLevel second it seems to do the commands correctly, but only when switching to On. When switching isOn: False and setting lightLevel to I.e. 20 and then switching back on, the light level will not be 20.

@famichiki can you test test this an let me know if this helps? If it seems to behave deterministically I could add it to the library.

@famichiki
Copy link
Author

famichiki commented Aug 24, 2024

I'm seeing the same behaviour as you described, so can only set the brightness after the light is on. However when using two attribute objects the transition is much faster as it doesn't do a fade.

But I've found that if you trigger a scene which has only lightLevel set without specifying isOn then the next time the bulb is switched on it will be at your desired brightness without switching if off if it's already on.

The following will create a hidden scene that specifies brightness only, triggers it, then immediately deletes it. If the light is on, the brightness will change, if it's off it will stay off.

from dirigera.devices.scene import Info, Icon, SceneType, Action, ActionAttributes

light = dirigera_hub.get_light_by_name("bathroom_light")

scene = dirigera_hub.create_scene(
    info=Info(name="temp_scene", icon=Icon.SCENES_BRIGHTNESS_UP),
    scene_type=SceneType.CUSTOM_SCENE,
    triggers=[],
    actions=[Action(id=light.id, type="device", enabled=True, attributes=ActionAttributes(lightLevel=30))],
)

scene.trigger()
dirigera_hub.delete_scene(scene.id)

I initially tried this with a USER_SCENE but the app caches programmatically deleted scenes weirdly, even though they are removed in the hub they reappear when the app loses connection with the hub (eg: wifi dropout) and clearing the app's cache doesn't help.

Perhaps the existing set_light_level method could be modified to check if isOn=False and if so then use technique?

My original goal with this was to set overnight hours where a light's default brightness was dimmer than during the daytime. For example, between midnight and 6am whenever I switched on my bathroom light it would switch on at 30% brightness.

Now that I know this is possible I've tried making a scheduled scene to achieve this, but had a few hiccups.

First of all, time: Optional[str] = None needs to be added to TriggerDetails, could you rectify that please?

class TriggerDetails(BaseIkeaModel):
    days: Optional[List[str]] = None
    time: Optional[str] = None
    controllerType: Optional[ControllerType] = None
    buttonIndex: Optional[int] = None
    clickPattern: Optional[ClickPattern] = None
    deviceId: Optional[str] = None
    offset: Optional[int] = None
    type: Optional[str] = None

Also could you please add support for endTriggerEvent and endTrigger to facilitate things like the following:

Ends at 6:00am
'endTriggerEvent': {'type': 'time', 'trigger': {'time': '06:00'}}

Ends after 6 hours.
'endTrigger': {'type': 'duration', 'trigger': {'duration': 21600}}, 'endTriggerEvent': {'type': 'duration', 'trigger': {'duration': 21600}}

So ideally I'd like to be able to create a scene as below that dims a switched off light to 30% between midnight and 6:00am, after which it will be restored to the previous brightness level.

from dirigera.devices.scene import Info, Icon, SceneType, Trigger, endTriggerEvent, TriggerDetails, Action, ActionAttributes

light = dirigera_hub.get_light_by_name("bathroom_light")

scene = dirigera_hub.create_scene(
    info=Info(name="bathroom_night_start", icon=Icon.SCENES_MOON),
    scene_type=SceneType.CUSTOM_SCENE,
    triggers=[
        Trigger(type="app", disabled=False),
        Trigger(type="time", disabled=False, 
            trigger=TriggerDetails(time='00:00'))],
        endTriggerEvent(type="time", disabled=False, 
            trigger=TriggerDetails(time='06:00'))],
    actions=[Action(id=light.id, type="device", enabled=True, attributes=ActionAttributes(lightLevel=30))],
)

It's important to create this as a CUSTOM_SCENE so it will be hidden. If you make a USER_SCENE, even if you simply go into the scene in the app and back out without editing any settings it will update the scene and add the isOn: False attribute.

Edit: I played around a lot and rewrote a lot, maybe it's helpful to someone.

@Leggin
Copy link
Owner

Leggin commented Sep 3, 2024

I will investigate your solution and make changes to the lib as soon as I find the time. If you want to contribute, you're very welcome!

@famichiki
Copy link
Author

Thanks, and I'd like to contribute some additional info to the readme when I also have some spare time.

@Leggin
Copy link
Owner

Leggin commented Sep 19, 2024

@famichiki I created a PR for the scene changes, can you check if this is correct?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants