Master virtual dimmer w/ maintained state when externally controlled


#1

1) Give a description of the problem
Virtual switch that I’m programming in my piston to be a master dimmer (for a group of philips bulbs) behaves erratically when other sources control the same dimmer bulbs.

2) What is the expected behavior?
Virtual dimmer can control group of dimming lightbulbs, but also notice when another mechanism (like the philips app) controls those lightbulbs and match their state, so I could use the virtual dimmer alongside other sources to control those bulbs seamlessly.

3) What is happening/not happening?
When I try to control the bulbs with the virtual dimmer, behavior is strange…most commonly, somehow the brightness shoots to nearly 100% after a couple weird swings of brightness. I believe this is due to the fact that my piston is looking for changes to both the virtual switch and the bulbs, so it creates a race condition/loop of sorts. I thought placing the switch in an if and the bulbs in an else or only looking for physical interaction with the switch (not programmatic) would fix the issue, but no luck. I suspect I’m missing some fundamentals of pistons…this is my first attempt. Should I use variables?

4) Post a Green Snapshot of the pistonimage

5) Attach any logs (From ST IDE and by turning logging level to Full)
Couldn’t quite figure this one out, sorry :frowning:

Thank you for any help. Apparently the dimmer issue is a long time one, I’m really hoping to come up with a robust solution.


#2

Yeah, I can see where this is going off the rails. When you have a piston such as this, with multiple triggers in it (the little lightning bolts on lines 18, 20, 30 and 32) then whenever ANY of those devices change they are going to cause the piston to execute in full…from the top down. So you’re getting in a quick loop really fast because you’re looking for changes on something that you’re changing.

Trying to test for “is physical” does not generally produce reliable results as many Device types do not properly send what is needed in order to determine that with absolute certainty. Besides, even if you took those out you’re likely in the same conundrum.

I’m not sure I know how to break out of this cycle as this is a puzzle. If you unsubscribe from events on line 30 then you won’t know if anything else changed the dimmers…but if you do subscribe then you’re almost certainly going to get stuck in a loop.

What would be nice is if you could temporarily stop a piston from processing specific events…but that does not exist. The only thing I can think of might be to set a time based “lockout” on this piston so that it only actually changes something after a brief delay. Mind you…it’s still going to receive all the events, but maybe if you just have it do nothing for a couple seconds then it could work.

The lockout is #4 in this link…


#3

It’s somewhat validating to hear this is, indeed, a difficult problem. Thanks for your insights, @Mike1616. I’ll check out lockout options and look into some other ideas I have as well. Hopefully others come along with some thoughts too.

I wonder if perhaps another option could be made in the physical/programmatic interaction menu for “webCoRE” interaction? So if the change was made in webCoRE, it could be excluded from triggering the same piston. Just a thought.


#4

Yeah, that would be possible. You could set a boolean variable at the top and that would tell you if you just entered the piston I’ve seen that done many times when people are controlling light switches that are turned on by motion sensors. But…I don’t know if that would be a good solution here. I think time might be better…or time is going to need to be considered at some point anyway…so you might as well just use that up front.


#5

I wrote up a the following piston that makes two lights in my basement and the basement stairs act as one single device. Changes to any of them (level or switch on/off) will result in the most recent switch becoming the “master” and pushing its values to the others. Because my dimmers take about 5 seconds to report changes, there’s a bit of a delay between one switch/dimmer changing and the others following suit, but it has worked great for me outside the delay:

Just ignore the greyed out sections… parts of the piston I’ve monkeyed with on and off but have them disabled now. You can just delete them to clean them up - I have them there to remind me what else I’ve tried or may revisit.


#6

@Mike1616 I’m experimenting with a few ways of doing it. Maintaining piston state myself may work as well.

@michicago I’m not seeing greyed out areas…


#7

Ah, interesting. I guess disabled statements are not copied into green snapshots. Didn’t know that!


#8

Yeah…or like @michicago does in his piston. His method is using a time based restriction, which is what I had in mind. But if you kept track of what you just changed so that you don’t try and change it again that could work too.


#9

I’m close to a nice robust solution for this. I’ll post it to Example Pistons once I’m content.