Hue lights Start Level Change

No, you have to refresh the bridge...not the individual lights. That's not my point at all.

Exactly part of why it is flawed. Refreshing the hub means downloading the entire hub configuration for all the groups, lights, scenes, hub configurations β€” everything. Then this has to be Parsed from JSON to a java map that groovy can understand (part of the slurped) and then almost all of that data will is thrown out just so you can update a few devices or groups. And all the scene data and all the device data not imported is discarded. A full hub refresh on a large hue system can take about 0.5 seconds or more. And the refresh command is a blocking command that initiates a non-blocking async call to the hue http api service which then returns the results to a result handler that is not part of the refresh command, because it is async. That refresh result then has no idea that you just need to capture changes or just need to capture the state of a single device. This gets problematic if you are not able to fully control hue by just the unit at System, or is the hue has some integrations of its own that that change the state. So now, you want to capture state, but you can never be accurate, just mostly right, because the hue system refresh is so heavy of an operation in He that you cannot check every 5 seconds or less without causing performance issues. And again, the system is now doing 100% of the work to update 1% of the devices.

This is wrong. It is fine for a once a minute or once every 5 minute interval thing. But when you just want to capture the real state of a bulb, you should be able to make that call which takes a few milliseconds, and if the refresh system could identify when the refresh has completed, then all that wasted work goes away, and we limit the chatter to only updating the specific light or group that we are interested in, and making it possible to now fire a capture state event immediately after a refresh event of just that one device has occurred.
It is not that he’s to understand, yet I feel like I am being pegged as the bad guy or the forum idiot because I am proposing a simple change that makes things better and that actually works right.

#1 you're not even listening to me....i was agreeing with you about the level change issue. So, take YES for an answer.

#2. You're just wrong because Hubitat has to update all of the light states every few seconds to catch any changes made outside of HE. Otherwise they wouldn't be picked up in HE.

What would be better here? Since bri ranges from 1-254, I suppose a bri_inc of -254 would bring a light at full brightness all the way down to 254-254 = 0, which Hue doesn't support and whose behavior I'm not sure is defined, but doing this on my official Bridge has always just made it as low as possible, presumably 1 (but definitely not off); I'm not sure how diyHue handles that. Are you thinking -253 (which would, at full brightness, be 254-253 = 1, a defined value), or more generally a maximum absolute value of the current brightness level minus one? Or am I missing something bigger?

I'd appreciate any input here, having worked on a custom Bridge integration (more on that below). Currently, I'm doing everything the way Hubitat does in the interest of making it as much of a drop-in replacement as possible, except for slight differences in Group behavior and extensions to features or addition of missing features, the reason I started it in the first place.

I also wrote my own Hue Bridge integration and contemplated whether to implement refresh() on individual bulb/groups or just for the Bridge device that would get everything. I may do it on individual bulbs/groups some day, but for now, I did it the same way Hubitat does--the Bridge for everything. My reasoning is that I have it doing an async HTTP call out to the Bridge anyway, so it does that, wakes up for the response, and parses some data there. Hue is limited to 50-ish lights and I'm not sure how many groups, and my guess is that parsing this data shouldn't take much longer than doing it for just one or two bulbs since I'm again guessing that the bulk of the time and work is spent doing the HTTP call and callback, not processing the response. I could be wrong. I don't really have good profiling tools in Hubitat to see for sure. I'm certainly open to changing this sooner if anyone finds a significant difference, and I might do it at some point anyway, but I'm guessing the behavior with doing more than a couple bulbs or groups at the same time would actually be worse (especially with rate limiting on the Bridge over HTTP). Again, totally open to data that may suggest a significant difference.

I also wasn't sure how to handle scenes. If you get just one scene from the Bridge, you can view the associated lights and their settings. However, that isn't retrieved if you just retrieve all scenes, and if you only retrieve it when the scene is first brought into Hubitat, there's no guarantee the user didn't change it later via another app--so "polling" of some kind would be required to make sure that information is still accurate. My integration doesn't handle updating light or group states at all after activating a scene, with my suggestion being that the user poll if needed. I may add in an option to automatically get the information for the associated scene (and lights/groups), but I think I'm more likely to just add in an option (or suggest to the user) that they refresh the Bridge for everything. Again, I'm not sure there'd be a significant performance difference and am open to ideas here.

I handle scenes as child devices of the group. The scene is a momentary switch device. Groups and lights support a refresh, which is a subset of the device refresh. By default, group and light refresh is disabled, but can be enabled and a custom interval defined. The hub device also has a refresh, and refresh intervals. All device refreshes are performed by the parent integration app. As such, if a hub refresh is performed, all child device refresh schedules are reset. If any child device refresh is performed the scheduled readership (if one is pending) is reset. The idea is that I never prohibit a manual refresh but any refresh resets the clock for the next refresh.
I do not, at this time, try to integrate my hue scenes with the other scene controller apps, as it would be easier to write a new one from scratch, so instead, I just trigger the scene from the he scene. It works beautifully now. I need to implement the whole gamut of light types still, and implement some more fine tuning before I release it. Once released, I will consider the scene controller app of my own, but I really think leveraging the built in one is the best choice as it will allow the Zigbee grouping to work well.

Interesting approach! I assume that only works with GroupScenes and not LightScenes, but most people who didn't use early versions of the Hue app probably only have GroupScenes as far as scenes that they care about go.

This is actually something anyone can implement--but as far as I know, only Hubitat themselves have done it, and only in the Groups app.

I was going to do it with light scenes too but I learned that with V2 there are no light scenes anymore and I never used V1 know if I am implementing correctly.

Actually, no you're not missing anything. Your implementation uses a briinc of 1 instead of -254 and this problem is not seen when using CoCoHue. That's kinda my whole point. What i can't tell is what affect the timing makes on the command. The timeframe issued by HE is 30 and yours is 40. Don't know if that would make any difference.

The one thing that does happen, obviously, is the dimmer level does not update in HE immediately. But it also doesn't update in the Hue app immediately. I have my poll time set to 10 seconds so that is the max amount of time the level might possibly be wrong. But the switch definitely doesn't turn off when using your implementation. Any plans on working on a regular dimmable bulb driver?

You must be using an earlier version--I think I misunderstood the Hue API and changed once I figured out that and also saw what Hubitat was doing (which I confess I also set up an empty diyHue setup to do). This is what I have now, which I think is what Hubitat also does:

def cmd = ["bri_inc": (direction == "up" ? 254 : -254), "transitiontime": 30]

But I might still be misunderstanding something. I do see that the Hue API says it "returns" the new brightness level, so maybe I should look at what I get in the callback response if that's what they mean (I've never bothered to look). I do notice that it seems to freak out the Hue Bridge and the right level takes a while to appear (even when looking at the Bridge directly, not related to Hubitat taking a while itself to get it based on polling)--an oddity I noticed with Hubitat's integration and can now maybe see why.

Well, I'll be sure to not update then....because the old version doesn't have the same problem when you start level change down. :slight_smile:

The problem is that when you issue a start level change down with -254 as the brightness, it turns the switch off, because it is assuming that you want the brightness to be -254 which is less than 0 so that is "off". When you stop the change early with the briinc 0 command, it takes a couple seconds to update the hub with the true value but it does update eventually. Are you not seeing the same?

I did some experimenting: Hue will try to set bri to 0 if the absolute value of a negative bri_inc value is greater than or equal to the current brightness (so, as we've both seen, this includes bri_inc: -254 when the current bri is 254 but also, say, bri_inc: -200 when the current bri is 150). By this I mean that the Bridge will report back bri: 0, despite this not being a defined value (the API says 1-254). PUTting a bri: 0 actually works too, presumably setting the bulb to its dimmest level like bri: 1 does, so I'd consider this either a gap in the API or undefined behavior (other "illegal" values throw errors as I'd expect). It should be noticed that this does not turn the bulbs off; that cannot be done with bri or bri_inc per both my understanding of the API docs and my real-world experience playing with the API. If DiyHue does this, they may be implementing something incorrectly.

This means that I should probably never send bri_inc: -254, since in all cases that would aim for bri: 0, apparently undefined behavior (though mysteriously their docs do allow for these values on bri_inc). I'll probably make this change at least handle the best-case scenario where the bulb is at 100%. But really, the absolute value of this should never be greater than the distance in the desired direction between the current level and 1 (for negative values) or 254 (for positive values, though I don't see this behavior there--in line with the documentation, it does appear to cap off at 254). However, choosing the value to send here would only be reliable if the level was last manipulate from Hubitat or a recent poll retrieved the correct value, so this could actually break things in other cases (or at least stop users from getting the full range of dimming). I see potential problems either way and am not sure what the best thing to do here is (unless, again, you manipulate the bulbs only from Hubitat--but even there, there are some concerns with scenes).

I wasn't sure because it appeared to stay at bri: 0 for a while, definitely more than a few seconds. However, without changing anything, I tried a bit later (not sure how long but under a minute), and it eventually "corrected" itself to bri: 1. Additionally, contrary to the API docs (or perhaps consistent with them but with the behavior not clearly defined), sending bri_inc: 0 didn't show me what level it currently stopped at but rather what level the original bri_inc was aiming to stop at, so the response from this PUT (which does indeed a bri value as the docs say and I wondered above)--and the state as retrieved from the Bridge afterwards, for that matter--is not as useful as I thought it would be. After a while, the Bridge does again correct the bri value to the actual value, just as it does for apparently mistaken zero values. I feel like there may be a problem with the Bridge here or at least some lack of clarity in the API docs.

Bri Inc: 0 and Bri: 0 are not the same things. I think you are getting yourself confused. Your old version sends this to start to dim:
bri": 1 transitiontime": 40

Then this to stop:
/bri_inc": 0

HE, sends this:
bri_inc": -254 /transitiontime": 30
and this:
/bri_inc": 0 /transitiontime": 30

What I'm saying is that theirs is wrong, because they are sending the increments while yours is correct (at least the old version) because you are sending the "destination" if you don't stop it early. Rather than increment down 254 steps, just say set the brightness to one, since that's the last point you'd want to stop if you didn't stop it early.. When you issue the bri-inc: 0, that stops the dimming whereever the light is. Then it updates to the correct dimming level a couple of seconds later. Do you see the difference between what you were doing and what HE is doing now?

Also, your old version has the MAJOR added benefit of not being able to dim past the end of the line brightness. Instead of running right past it to off like every other driver for every other dimmer.

I understand the difference between bri and bri_inc but got hung up on insisting on using bri_inc to change the level, even when it's clear that bri would work in either case since the destination is either 1 or 254 and (what I forgot despite doing this before...) that bri_inc: 0 can be used to stop either (not just one also initiated with bri_inc) mid-transition. I will definitely change this back in the next revision. Thanks for helping me think this through!

I do still see a possible problem on the Hue side: sending bri_inc: 0 does indeed actually stop the light at the current brightness, but as we've noticed above, it still takes a while to get the correct "new" brightness from Hue using any method that I can find. The response from a PUT with bri_inc: 0 (which the API docs say should return the new brightness) as well as a GET on the light itself both return the originally-specified "destination" brightness for a while (in my case it seems to take around one minute), not where it actually stopped. This gets corrected after a bit--and doesn't matter much for me with the way I use lights, but I could see it messing people up who use things that manipulate lights using both startLevelChange followed in a short time by a setLevel with a relative value (like a "set new level to current level minus 10"-type action in Rule Machine, which will not have the current value or be able to correctly calculate the new one, even after a refresh, until Hue sorts itself out...but nothing we can really do about that).

Thanks again!

You hit the nail right on the head with your last sentence. And the biggest indicator that there is nothing you can do about it....the level is wrong in the Hue App for a couple seconds after you stop brightening/dimming as well! So, the bridge takes a couple seconds to correct itself, Hubitat is going to need to poll the Bridge again to get the corrected value. I only have 14 lights on my Hue bridge, so I have polling at 10 seconds, so it is not incorrect for me very long.

The HUGE thing though is the switch not turning off. The switch turning off in Hubitat screwed up so many different things for me! I have automations that turn off other lights in the room when one is turned off. So, this always frustrated me about the Hubitat/Hue integration. It wasn't until I had yours to be able to compare to that I saw the difference. I was actually writing into the folks that wrote DIYHue to see if they could correct the switch going off on their side but they reported that their genuine "test" hub exhibited the same behavior. That's when I remembered yours and found the difference between the two.

One issue I found after updating to the latest drivers (without changing the startChanging method) is that my dimmable bulbs only flash briefly when I turn them on. I have to issue and effect (0) or a stopchagning to get get them to stay on. The on command doesn't seem to work the same as it used to. Any idea on that one?

Going back to the 2019-11-26 version of the RGBW driver corrected the problem. I didn't go forward to see which version it was introduced in.

Another nit-picky thing....with the RGBW driver, when you turn on a light that is in CT mode, it defaults to RGB mode, even if the bulb is actually in CT mode still. Don't know if that is corrected in a later version but I'm seeing that consistently as well.

Correction: It does eventually correct to CT mode...but when the bulbs are off, they all read RGB mode. It doesn't really matter, just a little strange.

I just updated the startLevelChange methods with the suggestions above.

I'll look into the colorMode issues. I have a really hard time getting colorMode: CT to stay for me at all because as of recent Bridge or bulb firmware versions, Hue really seems to like to use xy mode for everything--even for a lot of the "default" scenes like Read and Concentrate that were formerly CT--which neither Hubitat's nor my integration really supports (I pretend xy is RGB mode; no idea what Hubitat does, and I plan to figure out a better solution for this in the future if I can). This happens as reported by the Bridge itself. However, I'll see if I might be doing something odd to cause it to incorrectly report RGB instead of CT myself--I don't doubt that I might just not be noticing something here that is my problem (since the Bridge does it so much on its own when I don't want it to, I've almost tuned this out).

Not sure about the flashing-on thing, either, but I can look into that as well. I wonder if at least one of these might be related to me trying to report colorMode: EFFECTS when the bulb/group is put into "colorloop" mode, which is consistent with what it looks like Hubitat does for Z-Wave bulbs that support effects. I might just give up on trying to track this with that attribute (not even sure "EFFECTS" is a valid value, despite the fact that they do it: Color bulb capabilities and attributes) in favor of a custom attribute or something. I was never really happy with how I made that work (and Hue doesn't treat it as a special color mode, so it would be easier on me as well).

I think that is it. For some reason, it stays on colormode Effects for dimmable bulbs. I might just take your RGBW driver and try to "dumb it down" to a dimmable only and see if that corrects it. if it does, I'll send a pull-request through github.

Ah, yeah, I haven't tested that on dimmable-only bulbs and there could very well be something the driver is trying to parse that isn't there, causing some oddities. I have a working draft of a dimmable-only driver and was hoping to hold off on releasing it until I figured out some other things with the other drivers (like the excellent feeback I got on startLevelChange), but it would be pretty easy to try on your own, too--and would definitely avoid colorMode problems since there aren't any. :slight_smile:

My thinking exactly. About 1/3 of my lights are dimmable only (old Cree bulbs that I just can't throw away because they won't die and I'm cheap) 1/3 are CT only and the rest are RGBW. The CT have some funky stuff going on with Color name too...but again, that doesn't really affect functionality, just my OCD. :slight_smile:

Turns out....it was the "alert": "none". Took that out...bingo, no problem. I knew it would be something silly like that.