claytonjn / hass-circadian_lighting

Circadian Lighting custom component for Home Assistant
Apache License 2.0
778 stars 87 forks source link

Help with WAF #84

Closed broyuken closed 4 years ago

broyuken commented 4 years ago

First of all I want to say, I love circadian lighting and I use it in my home office every day, however I’m not allowed to use it in any other rooms yet because of one major issue from the wife. She absolutely HATES that if she adjusts the brightness of a light manually from the wall, CL will switch it back in a few seconds. Is there any way to check if a switch is manually adjusted and turn off CL for it?

claytonjn commented 4 years ago

No, I have thoughts about ways to implement that but as of yet have not had the time. Your best bet may be to disable the brightness adjustment in CL. Alternatively you could set up two CL switches for each group of lights, one for color temp and one for brightness; then you could use an automation to disable the brightness one when a switch is used.

broyuken commented 4 years ago

Is that a new option? I don't recall seeing it previously. That could be helpful on some lights, but unfortunately not the ones I'm having issues with. They are smart switches so they are brightness only. Is there an automation where I could disable the CL switch when the switch is used? I'm not sure how that would be created. If you have an example that would be super helpful.

claytonjn commented 4 years ago

If it's a dimmer that's controlling "dumb" lights there's no easy way to distinguish between when the physical switch is used or when CL dims (unless your particular switch reports physical vs virtual dimming) so there's no easy way to accomplish that in that case.

broyuken commented 4 years ago

Thats what I was afraid of. I might have to see if I can come up with something to determine that night mode should turn off, or see if I can enable a double tap on the switches to disable the switch or something along those lines.

Joshfindit commented 4 years ago

One thought since it seems like the wife in question is dimming digitally:

Track a “manually adjusted” property. This is probably best as a timestamp indicating when it was last manually adjusted, but the point of this would be:

If this light is known to be manually adjusted, don’t touch it.

The status would be set if the current value is significantly different than the expected value as this is a clear indication that it’s been changed externally. There may be a false positive if an automation triggers a change, but that’s something that can be tweaked on the back-end.

broyuken commented 4 years ago

That would be a great fix, if I'm adjusting it either via the wall or via an automation I don't want CL to mess with it. For example, if I have an automation to set one of my smart bulbs to blue, I don't want CL to switch it back. For that example I could have the CL switch turned off before I change the color, but if it was built in that would be that much better. Then maybe have a service that I could call in the middle of the night to undo the "don't touch it" flag?

broyuken commented 4 years ago

When you get this figured out, let me know, I would be more than happy to help you test.

mikeage commented 4 years ago

Do any of the scripts in https://github.com/claytonjn/hass-circadian_lighting/issues/51 help?

broyuken commented 4 years ago

They look like they may work, but it would be nice if this was built in.

broyuken commented 4 years ago

@claytonjn , do you think it would be possible to add a manually adjusted option to disable the CL switches? It looks like it’s possible to determine if a switch has been adjusted by seeing what Entity Controller is doing. Could you do something similar here?

claytonjn commented 4 years ago

I'm not familiar with Entity Controller, can you point me to some documentation?

broyuken commented 4 years ago

https://github.com/danobot/entity-controller

Specifically the 3.2 section under requirements

claytonjn commented 4 years ago

I'll have to look at that in more detail, but I'm not sure it will apply for this component. It seems that entity controller is a really fancy way of turning things on/off, so if it goes to turn something on and it's already on for example then it knows there was a manual override. That doesn't really work for CL because it only makes adjustments when lights are on, and the attributes that CL needs to look at to know if it's been adjusted manually aren't binary (on/off) but a range.

In actuality disabling CL when a light is manually adjusted shouldn't be that hard assuming lights from all integrations behave the same way in updating entity attributes. The hard part is the logic of when CL should be reenabled and the problem is that logic will be different for each individual.

broyuken commented 4 years ago

For the turning back on, I was thinking this could simply be handled by our own automations. Either turn them back on at midnight or something or reset them if everyone leaves the house.

broyuken commented 4 years ago

Hi, just checking in if there has been any progress or anything I could help with. I ran into a major issue with it last night that this would solve. I had turned my light a cool blue before bed so it gave off some light but wasnt super bright and I forgot to turn off CL. All of a sudden the light went on to a warm white and very bright waking her up. If you do implement the requested change, could you make sure it works if the color is set different to what CL expects it to be and then disable the switch?

gcorgnet commented 4 years ago

Very keen to see what could be done here as well. Following this issue, closely.

broyuken commented 4 years ago

Hi @claytonjn checking in again, is there anything you’d like me to help you test? I’d gladly provide feedback on things that could/should be tweaked to make this awesome component even better.

claytonjn commented 4 years ago

Nothing to report so far, been putting in long hours working from home so I just haven't had any time to work on "fun" development unfortunately. Here in Michigan things are changing every week and so we keep having to shift priorities, it might be weeks or months before I can even start to look at this :/

broyuken commented 4 years ago

No worries, I get it. This is just a side project that you do in your spare time for free. And things are crazy all over, I’m near Boston (another Dave and Chuck location) and they keep pushing the date for things to go back to normal.

If you do find time to get this working, I’d be more than happy to help you beta test this, and if it works you have a few coffees coming on me :)

broyuken commented 4 years ago

Hello, just checking in again. If there’s been no progress that’s cool, just checking. If there’s anything I can help with let me know.

claytonjn commented 4 years ago

Nope, no progress. This is going to be one of the first things I work on when I get time to work on this integration. Worked over 80 hours last week so no time for personal projects unfortunately.

broyuken commented 4 years ago

Just doing my monthly check-in to see how things are going. As always if there's something I can do to help let me know :)

basnijholt commented 4 years ago

@broyuken, I have implemented the exact thing you originally asked for.

A new configuration option only_once that if true, only adjusts the lights once when turning on, then if you manually change the lights, it will stay in that brightness and color.

broyuken commented 4 years ago

If you don’t manually adjust it will it continue to adjust like normal?

basnijholt commented 4 years ago

No, it will then only change color on turning on the light (or changing sleep_state or disable_state).

IIUC it is currently not possible to detect who changed the lights (automation vs manual).

broyuken commented 4 years ago

Ah, that’s not exactly what I was asking for then. I was hoping that if a light was adjusted to outside of a certain range then CL would know to turn itself off, either until a service turns it back on again or until the light is turned off

DoloresHA commented 4 years ago

Ah, that’s not exactly what I was asking for then. I was hoping that if a light was adjusted to outside of a certain range then CL would know to turn itself off, either until a service turns it back on again or until the light is turned off

I get around this by monitoring when the switch is pressed and turning off the circadian switch. My z-wave switches trigger an event when they are operated from the wall, so I have an automation that turns off CL if the brightness is adjusted from there.

elupus commented 4 years ago

A possible approach. Always just do relative adjusts. Ie keep track of a target value. Then move the current value (per light) against target by just a small amount (the amount being the speed of change of the target). That way if light is modified on a wall switch, lets say turn it to max. This component would only gradually dim it approaching wanted value over time not in one go. It would be way more acceptable in most scenarios.

broyuken commented 4 years ago

Ah, that’s not exactly what I was asking for then. I was hoping that if a light was adjusted to outside of a certain range then CL would know to turn itself off, either until a service turns it back on again or until the light is turned off

I get around this by monitoring when the switch is pressed and turning off the circadian switch. My z-wave switches trigger an event when they are operated from the wall, so I have an automation that turns off CL if the brightness is adjusted from there.

Could you share the automation? I may need to do the same for now.

basnijholt commented 4 years ago

I am implementing a feature take_over_control for https://github.com/home-assistant/core/pull/40626 that disables automatic adjusting of lights when manually changing the lights.

The feature isn't there yet but it will be ready today or tomorrow.

mikeage commented 4 years ago

Very nice. What happens when an adjustment is made, not from an HA call to light.turn_on, but via something like Alexa, either via HA or to the bulb directly?

basnijholt commented 4 years ago

Does Alexa make a light.turn_on service call?

I plan to only detect manually set changes when context.user_id is set and light.turn_on is called.

mikeage commented 4 years ago

If it goes to HA... I'm not sure. If it's direct, definitely not.

Is it possible to do the opposite -- treat all changes as disabling automatic adjustment except those from adaptive_lighting / circadian_lighting?

(for reference, I have some scripts in #51 that I'm using now; it's a bit ugly and kludgy, but it works. Basically, it works by comparing the current values to the expected values and if they differ "significantly", it assumes a manual change. Also delays and other stuff for robustness, but that's the main idea. I also have an input_select for whether a light is controlled automatically, with three states; On, Off, and Overridden, which means "don't touch it now, but after the light is shut off, reset the CL status to On. A detected change puts the state in Overridden, so when the light is reset (by being shut off), it resumes control automatically on the next time)

broyuken commented 4 years ago

I second this, if a switch is adjusted from the wall, it should not automatically adjust again until it is turned off and back on. This bugs the crap out of my wife and is the main reason why I am not running it at home.

Also thank you for including the context_id in this, that means I will be able to use it with the ignored_event_sources option that was just added to Entity Controller. I may finally be able to use these options AND keep a happy wife! Fingers crossed :) https://github.com/danobot/entity-controller/issues/192

basnijholt commented 4 years ago

You can already have the only_once option.

I will have to think about how it should work. It should work 100% of the time in a predictable manner.

I can already think of one edge case where the algo @mikeage suggests fails:

  1. light loses connection briefly
  2. light appears as unavailable (state switch from 'on' -> 'unavailable')
  3. light has a connection again (state switch from 'unavailable' -> 'on')

Now it will ignore this light all of the sudden.

broyuken commented 4 years ago

Only_once wouldn't solve the issue though. If I have a light that is on all day, I want it to continually adjust based on time of day. However if I set it to 50% brightness from the wall or from HA I don't want it to go back and continue adjusting. If the light gets turned off, and then back on again later it should go back to adjusting unless it is manually changed again.

basnijholt commented 4 years ago

unless it is manually changed again

I agree but it is hard to define what counts as manually changing.

Hypfer commented 4 years ago

I've implemented something similar before switching to this custom component.

To detect manual change, I've saved the previous automatically applied settings and compared them with the current settings in the next iteration. If there were any changes not done by the automation, the automation for that light would turn itself off.

Turning off the light would then reset these values and re-enable the automatic color temperature control.

elupus commented 4 years ago

that is what context is for :). If the context is not yourself, you can assume it's manual: See for example: https://github.com/danobot/entity-controller/commit/738968d6e4515e82180af93dffeb9addf970e417

broyuken commented 4 years ago

Couldn't you do change != adaptive_lighting

broyuken commented 4 years ago

If the context is not yourself, you can assume it's manual

Or if the context is not yourself then that means something else is controlling it and should take precedence and adaptive lighting should stand down.

Hypfer commented 4 years ago

@elupus But that doesn't necessarily mean that one wants to turn off the whole automation.

I for example use zigbee switches to dim the lights. They don't feature a context, but I also don't want the manual brightness control to turn off the color temperature control.

Hm. I guess a simple on/off switch for manual change detection would be insufficient here

elupus commented 4 years ago

@Hypfer why don't you want the zigbee switch to disable automatic control of the entity? You are manually changing the lights then. Imho any non adapting lighting control independent of source should disable the feature for that entity (probably that entity only). I suppose one could differentiate between brightness and color temperature, but then it gets tricky

Hypfer commented 4 years ago

@elupus My use-case is that I want to control all my lights using physical switches regarding on/off + brightness, but also want HA (or anything) to control the color temperature. Fully automatic operation would require stuff like motion sensors I think, but those aren't that reliable in my experience

Plus of course the rare cases where I manually want to set the color temperature and expect the auto control to turn off until I toggle the light off and on again

basnijholt commented 4 years ago

To detect manual change, I've saved the previous automatically applied settings and compared them with the current settings in the next iteration. If there were any changes not done by the automation, the automation for that light would turn itself off.

That sounds like a good idea but this will fail for Zigbee lights that often miss a message (which happens to me relatively often).

DoloresHA commented 4 years ago

However if I set it to 50% brightness from the wall or from HA I don't want it to go back and continue adjusting.

Does your switch fire some event or scene when you manually adjust it? I just use that in an automation to turn off switch.turn_off. From HA same goes, but you'd have to create a Lovelace button that does the service call.

For a lot of the feedback... To me it sounds like people just don't want circadian lighting. Or only want it in very specific cases. In which case you should just turn on the circadian switch then. Or have an automation to disable it when your wife gets home lol.

"this awesome automatic lights adjuster keeps adjusting my lights!" I know I'm being a bit of a stick in the mud but I don't see how the switch to turn on or off circadian lighting doesn't address most use cases, and very simply.

elupus commented 4 years ago

Right. I still think context is the key here. You look at context to see who is doing the controlling. If it's the automatic adjustment, just ignore it. If it's something else, check (brightness adjustment is enabled & brightness changed) -> disable check (temperature enabled & temperature changed) -> disable. Other cases is just ignore.

broyuken commented 4 years ago

The important thing to keep in mind here is if the lights are adjusting automatically and people are happy with it then they won't be manually changing it. If someone changes it, it's because the lights aren't at a level that makes them happy. So ANY adjustment outside of CL should be considered manual and turn off further adjustments.

Perhaps it's late at night but they're trying to read and the lights are too dim. So they turn them up brighter. Perhaps someone has an automation to turn a light a certain color to remind them of something. These lights should not continue to automatically adjust until the lights have been turned off and turned on at some point later. There are countless reasons why people would want the lights to stop automating.

basnijholt commented 4 years ago

We cannot consider all cases to be manual, see my example here.

broyuken commented 4 years ago

@elupus My use-case is that I want to control all my lights using physical switches regarding on/off + brightness, but also want HA (or anything) to control the color temperature. Fully automatic operation would require stuff like motion sensors I think, but those aren't that reliable in my experience

Plus of course the rare cases where I manually want to set the color temperature and expect the auto control to turn off until I toggle the light off and on again

Could you create 2 instances, one that does color and one that does brightness, and only turn one of them off when you want to control brightness from the wall and allow the other color one to continue?