Webcore not saving and restoring correct HSL values for Hue bulb


#1

1) Give a description of the problem

HSL values are incorrect when saving and restoring from a variable.

When any water detection sensor detects water, the piston should:

  1. Capture current hsl values, then wait for a second
  2. Change the bulb to a pre-set color (using hsl values), then wait for a second
  3. Restore the bulb to its previous state via hsl values

Example: I set the bulb to a red color. Here are the values from the different places:
IDE: hue: 100 / sat: 100 / level: 25
Saving current hsl to variables in webcore: hue: 360 / sat: 100 / level: 25
Restoring from variables in webcore: hue: 219 s/ at: 61 / level: 100

2) What is the expected behaviour?
Correct hsl values are stored, then the bulb is restored to those values

3) What is happening/not happening?
Incorrect values are stored, then another set of incorrect values are restored.

**4) Post a Green Snapshot of the piston!

5) Attach logs after turning logging level to Full

9/12/2020, 2:54:41 PM +199ms
    +0ms ╔Received event [Home].time = 1599947682530 with a delay of -1332ms
    +2079ms ║RunTime Analysis CS > 1932ms > PS > 103ms > PE > 44ms > CE
    +2082ms ║Runtime (47375 bytes) successfully initialized in 103ms (v0.3.110.20191009) (2081ms)
    +2084ms ║╔Execution stage started
    +2140ms ║║Executed physical command [Light - Couch End Table].setColor([[hue:100, saturation:100, level:25]]) (6ms)
    +2141ms ║║Executed virtual command [Light - Couch End Table].setHSLColor (9ms)
    +2154ms ║║Calculating (string) Restored to - Hue: + (string) 219 >> (string) Restored to - Hue: 219
    +2157ms ║║Calculating (string) Restored to - Hue: 219 + (string) / Sat: >> (string) Restored to - Hue: 219 / Sat:
    +2165ms ║║Calculating (string) Restored to - Hue: 219 / Sat: + (string) 61 >> (string) Restored to - Hue: 219 / Sat: 61
    +2167ms ║║Calculating (string) Restored to - Hue: 219 / Sat: 61 + (string) / Level: >> (string) Restored to - Hue: 219 / Sat: 61 / Level:
    +2174ms ║║Calculating (string) Restored to - Hue: 219 / Sat: 61 / Level: + (string) 100 >> (string) Restored to - Hue: 219 / Sat: 61 / Level: 100
    +2178ms ║║Restored to - Hue: 219 / Sat: 61 / Level: 100
    +2179ms ║║Executed virtual command [Light - Couch End Table].log (2ms)
    +2181ms ║╚Execution stage complete. (98ms)
    +2182ms ╚Event processed successfully (2182ms)
    9/12/2020, 2:54:31 PM +89ms
    +1ms ╔Received event [Home].time = 1599947672810 with a delay of -1721ms
    +1357ms ║RunTime Analysis CS > 1234ms > PS > 87ms > PE > 36ms > CE
    +1360ms ║Runtime (47373 bytes) successfully initialized in 87ms (v0.3.110.20191009) (1358ms)
    +1361ms ║╔Execution stage started
    +1378ms ║║Cancelling statement #3's schedules...
    +1435ms ║║Executed physical command [Light - Couch End Table].setColor([[hue:61, saturation:61, level:100]]) (43ms)
    +1436ms ║║Executed virtual command [Light - Couch End Table].setHSLColor (45ms)
    +1439ms ║║Executed virtual command [Light - Couch End Table].wait (0ms)
    +1441ms ║║Requesting a wake up for Sat, Sep 12 2020 @ 2:54:42 PM MST (in 10.0s)
    +1444ms ║╚Execution stage complete. (84ms)
    +1445ms ║Setting up scheduled job for Sat, Sep 12 2020 @ 2:54:42 PM MST (in 9.996s)
    +1452ms ╚Event processed successfully (1452ms)
    9/12/2020, 2:54:22 PM +468ms
    +0ms ╔Received event [Home].test = 1599947662467 with a delay of 0ms
    +111ms ║RunTime Analysis CS > 22ms > PS > 57ms > PE > 33ms > CE
    +114ms ║Runtime (47366 bytes) successfully initialized in 57ms (v0.3.110.20191009) (113ms)
    +115ms ║╔Execution stage started
    +160ms ║║Condition #2 evaluated false (40ms)
    +234ms ║║Comparison (enum) dry is (string) dry = true (2ms)
    +236ms ║║Condition #21 evaluated true (75ms)
    +238ms ║║Condition group #1 evaluated true (state did not change) (119ms)
    +241ms ║║Cancelling statement #22's schedules...
    +257ms ║║Executed virtual command setVariable (3ms)
    +273ms ║║Executed virtual command setVariable (3ms)
    +308ms ║║Executed virtual command setVariable (3ms)
    +319ms ║║Calculating (string) Captured -- Hue: + (string) 360 >> (string) Captured -- Hue: 360
    +322ms ║║Calculating (string) Captured -- Hue: 360 + (string) / Sat: >> (string) Captured -- Hue: 360 / Sat:
    +326ms ║║Calculating (string) Captured -- Hue: 360 / Sat: + (string) 100 >> (string) Captured -- Hue: 360 / Sat: 100
    +329ms ║║Calculating (string) Captured -- Hue: 360 / Sat: 100 + (string) / Lvl: >> (string) Captured -- Hue: 360 / Sat: 100 / Lvl:
    +332ms ║║Calculating (string) Captured -- Hue: 360 / Sat: 100 / Lvl: + (string) 25 >> (string) Captured -- Hue: 360 / Sat: 100 / Lvl: 25
    +336ms ║║Captured -- Hue: 360 / Sat: 100 / Lvl: 25
    +337ms ║║Executed virtual command log (2ms)
    +340ms ║║Executed virtual command wait (1ms)
    +342ms ║║Requesting a wake up for Sat, Sep 12 2020 @ 2:54:32 PM MST (in 10.0s)
    +360ms ║╚Execution stage complete. (245ms)
    +368ms ║Setting up scheduled job for Sat, Sep 12 2020 @ 2:54:32 PM MST (in 9.975s)
    +380ms ╚Event processed successfully (380ms)

#2

Your image above is a bit hard to read, so I cannot help you…

To upload pics here, please use this button when posting:

pic


#3

If you click the image, doesn’t it expand to be larger? It does for me on the forum.


#4

All I see is a tiny (fuzzy) image… I cannot read the code


#5

That’s annoying, sorry; was mobile for a while. I uploaded this to the forum, so hopefully it works better.


#6

Thanks for that.
That image button has the added benefit of keeping the pics “in-house”(AKA: reliable)


I am going to ignore your trigger for the moment, and start with a little math…

After playing with this for awhile, it actually makes sense to me…
100% = 360° (or 0°)
50% = 180°
25% = 90°
etc…

  • You can take any degree and divide by 3.6 to get the percentage… or
  • You can take any percentage and multiply by 3.6 to get the degree.
    (each Device Handler has different expectations)

So for example, if you want to convert a degree into a decimal, you can use an Expression like:
round(([Light - Couch End Table : hue] / 3.6),0)
… and you will get an integer between 0 and 100.

For a bit deeper look at conversions, here is a couple of old posts of mine.


Everything online color-wise is our feeble attempt to convert an analog thing such as color into a digital thing like integers. The most we can expect is a semblance of accuracy.
(IE: my hue usually restores within about 2 pts of the original)


#7

I believe this is in reference to your line 43…
Set color to H:223° / S:61% / L:100

Notice how in the log is appears as:
║║Executed physical command [Light - Couch End Table].setColor([[hue:61, saturation:61, level:100]])

So if we take your request of Hue 223… Divide by 3.6… we get 61.94…
(or floored to 61 as seen in webCoRE’s log)

Taking it one step farther for the “return trip”:
Notice how 61 times 3.6 = 219.6… Again floored down to 219 in webCoRE.
(this is typically why a starting hue of 223 would return as 219 after two conversions)

Thankfully, usually a hue off by 4° (or 1%) is not detectable to the human eye…


As far as for the reset… I overlooked it earlier, but webCoRE sent the correct command:

Executed physical command [Light - Couch End Table].setColor([[hue:100, saturation:100, level:25]])

… but 0.013 seconds later, the bulb had not registered the new color yet.

You can try adding a small WAIT between the reset, and the final log to console.
(to hopefully give the bulb time to properly report the new status to the hub)


#8

Thanks for the in-depth responses. I didn’t realize that the different locations were showing me data in different ways. That explains a lot about why it wasn’t working the way I thought.

I’ll also keep in mind the time difference between the light being changed and the log being recorded. The light wasn’t returning to the correct color, too - e.g. I started on red, it changed to the blue then dimmed back down but never turned red again.

I’m going to take another look at this and make sure the colors I set up in the piston reflect what my brain is thinking.


#9

So I did a bit more testing - and it appears that the system is auto-converting the degrees into decimals for me, so i don’t need to worry about that in the piston.

What I am noticing, though - is that it appears the correct values are being passed through the piston and sent to smartthings, but the Hue light in real life is not returning to the correct color. It appears that the second time the piston is triggered, the color that the bulb returns to is the original color from run #1.

I have noticed that the bulb will go to the correct brightness, but not the correct color. Every once in a while, the piston does produce the desired result where the bulb goes back to the original color.

Here’s a test I did:

  1. Set color to green using Hue app on android
  2. Run piston
  3. Logged: Captured – Hue: 126 / Sat: 100 / Lvl: 100
  4. Bulb changed to correct color as manually set in the piston (aqua-ish)
  5. Bulb changes to the original green color
  6. Logged: Restored to - Hue: 126 / Sat: 100 / Level: 100
  7. Set color to pink using Hue app on Android
  8. Run Piston
  9. Logged: Captured – Hue: 126 / Sat: 100 / Lvl: 100
  10. Bulb changed to correct color as manually set in the piston (aqua-ish)
  11. Bulb changes to the original green color
  12. Logged: Restored to - Hue: 126 / Sat: 100 / Level: 100

Not sure where the hangup is in the process. Thoughts?


#10

Yes… Most of my text above was to demonstrate what happens behind the scenes…
(so hue 223° > 61% > 219° no longer raises any flags)


I have a few thoughts in my head, but I would need to see the current piston and a Full log showing an error to properly analyze.


Pro Tip:

With a 10 sec WAIT in play, I would stall at least 22 sec between each test.
If you are just winging it, I’d stall 30+ sec in between tests…
(if you are watching the log, then 12+ sec after the last command has executed, and the last log written)

This basically ensures that the “slate is clean” before moving on to the next test.

To clarify, do not touch the color on this bulb until after the stall mentioned above.
(and once you change the color externally, wait an additional +5 sec to give the bulb time to report correctly to the hub, and finally, you can press Test)


#11

I thought maybe there was a delay in the whole system between changing the color and that color being ‘registered’ or what-not. I did a few tests where I waited multiple minutes and still came across that same issue. That’s why there is the 10 second waits - but, no matter the length of the waits the issue persisted.

Luckily, I still have the logs from the above test. I only have the logs from the two runs I did, and the piston that generated them.

9/14/2020, 6:31:09 PM +732ms
+2ms ╔Received event [Home].test = 1600133469729 with a delay of 2ms
+172ms ║RunTime Analysis CS > 31ms > PS > 83ms > PE > 58ms > CE
+175ms ║Runtime (48127 bytes) successfully initialized in 83ms (v0.3.110.20191009) (170ms)
+176ms ║╔Execution stage started
+223ms ║║Condition #2 evaluated false (40ms)
+253ms ║║Comparison (enum) dry is (string) dry = true (2ms)
+256ms ║║Condition #21 evaluated true (31ms)
+257ms ║║Condition group #1 evaluated true (state did not change) (74ms)
+260ms ║║Cancelling statement #22's schedules...
+280ms ║║Executed virtual command setVariable (3ms)
+292ms ║║Executed virtual command setVariable (4ms)
+303ms ║║Executed virtual command setVariable (4ms)
+315ms ║║Calculating (string) Captured -- Hue: + (string) 126 >> (string) Captured -- Hue: 126
+320ms ║║Calculating (string) Captured -- Hue: 126 + (string) / Sat: >> (string) Captured -- Hue: 126 / Sat:
+324ms ║║Calculating (string) Captured -- Hue: 126 / Sat: + (string) 100 >> (string) Captured -- Hue: 126 / Sat: 100
+328ms ║║Calculating (string) Captured -- Hue: 126 / Sat: 100 + (string) / Lvl: >> (string) Captured -- Hue: 126 / Sat: 100 / Lvl:
+331ms ║║Calculating (string) Captured -- Hue: 126 / Sat: 100 / Lvl: + (string) 100 >> (string) Captured -- Hue: 126 / Sat: 100 / Lvl: 100
+335ms ║║Captured -- Hue: 126 / Sat: 100 / Lvl: 100
+339ms ║║Executed virtual command log (4ms)
+343ms ║║Executed virtual command wait (0ms)
+344ms ║║Waiting for 1000ms
+1349ms ║║Cancelling statement #3's schedules...
+1375ms ║║Executed physical command [Light - Couch End Table].setColor([[hue:61, saturation:61, level:100]]) (12ms)
+1376ms ║║Executed virtual command [Light - Couch End Table].setHSLColor (15ms)
+1380ms ║║Executed virtual command [Light - Couch End Table].wait (1ms)
+1382ms ║║Waiting for 2000ms
+3395ms ║║Executed physical command [Light - Couch End Table].setColor([[hue:35, saturation:100, level:100]]) (6ms)
+3396ms ║║Executed virtual command [Light - Couch End Table].setHSLColor (7ms)
+3401ms ║║Executed virtual command [Light - Couch End Table].wait (0ms)
+3402ms ║║Waiting for 1000ms
+4416ms ║║Calculating (string) Restored to - Hue: + (string) 126 >> (string) Restored to - Hue: 126
+4421ms ║║Calculating (string) Restored to - Hue: 126 + (string) / Sat: >> (string) Restored to - Hue: 126 / Sat:
+4432ms ║║Calculating (string) Restored to - Hue: 126 / Sat: + (string) 100 >> (string) Restored to - Hue: 126 / Sat: 100
+4436ms ║║Calculating (string) Restored to - Hue: 126 / Sat: 100 + (string) / Level: >> (string) Restored to - Hue: 126 / Sat: 100 / Level:
+4445ms ║║Calculating (string) Restored to - Hue: 126 / Sat: 100 / Level: + (string) 100 >> (string) Restored to - Hue: 126 / Sat: 100 / Level: 100
+4451ms ║║Restored to - Hue: 126 / Sat: 100 / Level: 100
+4452ms ║║Executed virtual command [Light - Couch End Table].log (2ms)
+4459ms ║║Executed virtual command [Light - Couch End Table].setVariable (3ms)
+4465ms ║║Executed virtual command [Light - Couch End Table].setVariable (3ms)
+4473ms ║║Executed virtual command [Light - Couch End Table].setVariable (4ms)
+4484ms ║╚Execution stage complete. (4308ms)
+4486ms ╚Event processed successfully (4486ms)
9/14/2020, 6:30:16 PM +34ms
+3ms ╔Received event [Home].test = 1600133416030 with a delay of 3ms
+143ms ║RunTime Analysis CS > 28ms > PS > 59ms > PE > 57ms > CE
+146ms ║Runtime (48127 bytes) successfully initialized in 59ms (v0.3.110.20191009) (140ms)
+148ms ║╔Execution stage started
+194ms ║║Condition #2 evaluated false (39ms)
+223ms ║║Comparison (enum) dry is (string) dry = true (2ms)
+226ms ║║Condition #21 evaluated true (31ms)
+227ms ║║Condition group #1 evaluated true (state did not change) (72ms)
+231ms ║║Cancelling statement #22's schedules...
+252ms ║║Executed virtual command setVariable (3ms)
+262ms ║║Executed virtual command setVariable (3ms)
+270ms ║║Executed virtual command setVariable (2ms)
+284ms ║║Calculating (string) Captured -- Hue: + (string) 126 >> (string) Captured -- Hue: 126
+288ms ║║Calculating (string) Captured -- Hue: 126 + (string) / Sat: >> (string) Captured -- Hue: 126 / Sat:
+291ms ║║Calculating (string) Captured -- Hue: 126 / Sat: + (string) 100 >> (string) Captured -- Hue: 126 / Sat: 100
+295ms ║║Calculating (string) Captured -- Hue: 126 / Sat: 100 + (string) / Lvl: >> (string) Captured -- Hue: 126 / Sat: 100 / Lvl:
+298ms ║║Calculating (string) Captured -- Hue: 126 / Sat: 100 / Lvl: + (string) 100 >> (string) Captured -- Hue: 126 / Sat: 100 / Lvl: 100
+302ms ║║Captured -- Hue: 126 / Sat: 100 / Lvl: 100
+307ms ║║Executed virtual command log (4ms)
+311ms ║║Executed virtual command wait (1ms)
+312ms ║║Waiting for 1000ms
+1318ms ║║Cancelling statement #3's schedules...
+1337ms ║║Executed physical command [Light - Couch End Table].setColor([[hue:61, saturation:61, level:100]]) (6ms)
+1338ms ║║Executed virtual command [Light - Couch End Table].setHSLColor (9ms)
+1341ms ║║Executed virtual command [Light - Couch End Table].wait (0ms)
+1342ms ║║Waiting for 2000ms
+3354ms ║║Executed physical command [Light - Couch End Table].setColor([[hue:35, saturation:100, level:100]]) (4ms)
+3355ms ║║Executed virtual command [Light - Couch End Table].setHSLColor (6ms)
+3360ms ║║Executed virtual command [Light - Couch End Table].wait (0ms)
+3361ms ║║Waiting for 1000ms
+4375ms ║║Calculating (string) Restored to - Hue: + (string) 126 >> (string) Restored to - Hue: 126
+4380ms ║║Calculating (string) Restored to - Hue: 126 + (string) / Sat: >> (string) Restored to - Hue: 126 / Sat:
+4388ms ║║Calculating (string) Restored to - Hue: 126 / Sat: + (string) 100 >> (string) Restored to - Hue: 126 / Sat: 100
+4392ms ║║Calculating (string) Restored to - Hue: 126 / Sat: 100 + (string) / Level: >> (string) Restored to - Hue: 126 / Sat: 100 / Level:
+4400ms ║║Calculating (string) Restored to - Hue: 126 / Sat: 100 / Level: + (string) 100 >> (string) Restored to - Hue: 126 / Sat: 100 / Level: 100
+4404ms ║║Restored to - Hue: 126 / Sat: 100 / Level: 100
+4406ms ║║Executed virtual command [Light - Couch End Table].log (1ms)
+4411ms ║║Executed virtual command [Light - Couch End Table].setVariable (3ms)
+4417ms ║║Executed virtual command [Light - Couch End Table].setVariable (3ms)
+4423ms ║║Executed virtual command [Light - Couch End Table].setVariable (2ms)
+4434ms ║╚Execution stage complete. (4287ms)
+4436ms ╚Event processed successfully (4436ms)

#12

Thanks, but as mentioned above, I would also need to see the current piston…

IF it matches exactly with the log above, then cool…

… but if the piston has changed since 9/14/2020 @ 6:30 PM, then I would need to see the current green snapshot and a new log.


#13

Apologies!

I added the piston to my post above. The piston I added generated the logs in that post.


#14

Thanks!

From your posts, I believe that at:

  • 6:29:?? = you set the color to green using Hue app
  • 6:30:16 = you pressed Test and it worked (returned to green)
  • 6:30:?? = you set the color to pink using Hue app
  • 6:31:09 = you pressed Test and it failed (captured & returned to green instead of pink)

If this breakdown is correct, then I have two thoughts:

(1) I cannot tell from the log above, but just to re-iterate my earlier comments.
The second color should not be touched until the previous piston has completely finished, plus at least an additional 12 seconds. Once the color has changed, there needs to be more delay before testing the piston. (at least another 5 sec) In the example above, there are 53 seconds between tests. This means that the only acceptable time to touch the color in the app would have been a tiny 18 sec window from:
6:30:46 and 6:31:04

There is no way for me to tell if you did this or not, but I would expect errors if you changed to pink at any other time. (keep in mind that in a normal use, the color would already be active for a LONG time before the real trigger)

(2) This angle is a bit harder to talk about, so I am really hoping that you were just rushing above, and a slower more methodical way of testing would resolve this… But, if the above tips do not resolve this, then read on… (however I am not responsible for any grey hair, LOL)


In a nutshell… Bulbs typically register “color” in a few different ways…

  • colorTemp (often 2700 - 6400) which changes the “warmth/coolness” of the bulb
  • color = which changes a hex code that gets converted into something understood by the device
  • HSL = which changes hue, saturation and level to integers

The tricky part is:

  • If you change the colorTemp, you will often find the hue & saturation untouched.
  • If you change the color, you will often find the hue & saturation untouched.
    (Those sentences are worth reading twice)

A good rule of thumb is, if you are trying to capture & restore HSL, then make sure the bulb is currently seen as a HSL color. (IE: do not change color or colorTemp and expect HSL to capture correctly)

I cannot emphasize enough that #1 in this list is much easier to deal with.


#15

I can definitely tell that I did not manually change the color of the bulb using the Hue app while the piston was running; I waited until after the piston was finished and after the bulb was supposed to change back to its original color.

I’m not exactly sure how to “make sure the bulb is currently seen as an HSL color”. The piston should be capturing the HSL values, right?

Here’s the newest piston (I removed the section that sets the variables back to zero after the piston runs. I did this originally to make sure the piston was starting with no pre-set values.)

So I re-ran the test while waiting a pretty long time between steps, ~5 minutes and it appears to function just fine. Is there a rule of thumb or something that dictates how long to wait to ensure that the color is captured and restored correctly? Where did the 12 seconds and 5 seconds you referenced above come from?

One thing I was thinking about doing is having a ‘notification lamp’ for things like this, including doorbell rings, etc. So being able to correctly time the light color changes is very helpful.

Thank you SO much for taking the time to help me - all the information you provided is extremely helpful and valuable.


#16

Honestly, this is based on years of astute observations, LOL

The 12 seconds (or more) after the very last action is based on potential semaphore delays taking 10-11 seconds… with one extra sec for good measure… This number is “written in stone” when I do my testing.

The 5 sec after changing a color is based on delays found in many devices… (where they are slow to update their new status to the hub) This 5 sec can be very different between devices. (some thermostats take 30 sec or more to update the hub, but some devices report back in under a second) This number was an educated guess, that can be tweaked depending on the device. (if unsure, wait longer, LOL)


I have a centrally located light that I use for this, and it works very well.

  • I avoid manually change the color on that bulb
  • I keep it out of external Scenes
  • I am also careful to totally avoid using fades on that bulb.

It is reserved as my “Notification-Bulb”, so all colors are changed via webCoRE’s logic.

Depending on the event, the light may turn any number of colors…
… with each color representing different alerts for me.


Pro Tip:

If webCoRE makes all of the changes via HSL, then all of your captures & restores should work well. (I believe the bonus 5 sec after the color change can be dropped, since webCoRE is making the color change, instead of an external app)


#17

This is definitely something good for me to keep in mind. I see a lot of semaphores for some reasons (randomly across other pistons). I’m also going to start implementing the 5 second rule for the light color changes.

How do you handle the notification light receiving multiple triggers within a short timespan? Do you queue them up or something? If I set up a notification bulb, I’ll do as you have yours - controlled only via webcore.


#18

This is a great question, but it is also one that I should not answer…

My time here in the forum is typically generic/basic tips that can benefit everyone…
When we start talking about truly custom work (or any of my masterpieces), I’d prefer to chat privately while “on-the-clock”.


To say this another way:
I only reveal about 10% of my capabilities here…
I hope you can understand that my best coding is reserved for my clients.


#19

I only reveal about 10% of my capabilities here…
I hope you can understand that my best coding is reserved for my clients.

For sure! The fact that you help here at all is something I’m grateful for. Besides, if this is only 10% of your skills in coding :exploding_head::exploding_head::exploding_head: