Tri-State (ON/AUTO/OFF) Switch

What do you guys think about switches (for example for lighting) with three states? I know there is no way to do this without custom logic in rules. I just want to start some converstation about it.

Most of the lights here are paired with motions detectors or activity detection on computers, but sometimes I want to keep the lights ON or OFF if doing near motion-less activities like reading or a guest sleeping in the living room.

For me it feels like having the lights on AUTO most of the time, but switching over to ON or OFF in these particular situations would be super cool.

What do you think? Is it useless? Do you already do it? Using seperate switchis to turn off the automation? Let me know :slight_smile:

I think you’re asking about a master on/off switch for each rule? Or at least the ability to suspend the execution of specific rules.

I can see plenty of occasions where I would want to do that. But little to no time to implement it.

I wonder if you could create a separate proxy-style switch item for each rule and then use it’s state in the when parameters of the rule to determine if the rule should complete or not. I don’t know if you can combine && and or states being checked against though.

This description kind of fits, what I am thinking about, yes.

Creating proxy-style items is possible, but we would also have to put the logic into an if block, to only run the rule when the rule-switch is turned on. Adding it to the when block only is not possible, because these are truly events. They fire WHEN something happens on the event bus, not IF something happens.

I also see no way to do something like this in rules, as we cannot inject logic into rules from outside, or I just don’t know how.

You can only ‘or’ rule conditions there is no ‘and’ support. If you search around you’ll find the information somewhere that says why but as it stands you can only ‘or’.

I’ve not really implemented this yet so still remains to be done for me but I’m thnking I’ll end up with multi items.

There is always the base switch that is ‘bound’ to the light be it zwave or in my case just an external rpi with an RF transmitter. That needs to stay as a simple ON/OFF switch itself can’t do any more than that. Say it’s called b_Hall_Light (b_ for bound but use whatever suits your naming convention).

I will have a proxy item for that switch say p_Hall_Light. Then I’ll create one rule file that’ll handle the two events of OFF and ON for p_Hall_Light. ON will just be pushed straight through to b_Hall_Light, OFF likely be delayed via Timer (something like 2 seconds) for reasons to come clear below hopefully. No other rules or events should directly deal with the bound b_Hall_Light put them all through the proxy p_Hall_Light.

Some possible reasons for controlling the light, possibly fed from different sensor data:
Front Door opened
Hall PIR opened
Security system - be it presence off and just simulating activity or Alarm triggered.
Manual override

For the first two I’d just have an open and closed (maybe delayed) rule that sent p_Hall_Light ON and OFF respectively. This keeps the PIR/Reed rules very short and simple which is good for creation and on going maintenance.

With the manual override I’d have another simple switch item. It would have a simple rule file to pass through it’s own ON/OFF changes to p_Hall_Light, but it would have another rule to monitor p_Hall_Light change to OFF and it’ll re-enforce p_Hall_Light ON if it needs to based on it’s state.

The reason for a simple Timer delay when p_Hall_Light goes OFF before passing to b_Hall_Light is to stop it flicking OFF and then back ON again. All the events will happen on the proxy item but won’t be passed through realtime, hence manual override will likely have triggered proxy ON again before bound OFF was sent, last change will always go through.

The rules in the security system will just worry about doing what they feel they need to do. So if it has decided to turn the Hall light on for an hour that’s what it’ll do and maintain that whilst nothing in its world of business logic dictates any change required. Come the end of the hour and the security system says let turn off the Hall light, manual override will still win out because it’ll turn the light back on before it’s actually gone off.

If the alarm system is triggered it might want to do the same as manual override but only if astro reports the world as Dark.

For me this keeps each area isolated and the rules simple, hence coding effort reduced as well cross contamination of rules and business logic. You don’t have to code the PIR rule with any information about the manual override switch.

And you could easily expand it to using groups if you wanted to manage multiple lights in one group or even several groups with different manual overrides.

You do also need to be mindful not to create more than one ‘active’ style rule. By that consider manual override to be an ‘active’ rule such that it will always try and turn the light ON if someone turns it OFF. Don’t create another rule that actively tries to turn a light OFF and enforce it otherwise your OH system will spiral out of control and implode. :exploding_head: You could put code in the manual override rule to protect against that but it’s about time, effort, need and likely reality.

Now that were some in-depth details. Thanks for that!

It looks like the proxy item is the way to go here. Just came to my mind: A switch actually has another state: UNDEF (undefined). Not sure if this could act as an AUTO position for the proxy item though.

We could implement into our rules or funcitons, that those will only control automatic, presence-based lighting when the Proxy Item’s state is UNDEF (read AUTO) and otherwise force it to whatever the proxy item’s current state is.

The Expire binding can post UNDEF to items, so it should be possible as well from within rules and sitemaps, shouldn’t it?

There are quite a few design patterns around that might be worth considering like the Dead Mans Switch mentioned on this post.

Thing is you need to consider which ones are right for you. For me I can only send ON and OFF to my physical light switch it’ll never tell me if someone has pressed the button.

Yes it is possible to set a state to UNDEF (or more precisely NULL) in a rule, don’t know about sitemap. A quick look around and you have to create a temporary item that will adopt the state of NULL which you can then pass to something like postUpdate. postUpdate/sendCommand both seem to protect themselves against being sent NULL direct! All seems a little dirty to me so I’d avoid using it myself, don’t know enough about where it is going long term.

I’d just implement the proxy as multi state if you want it to have the AUTO feature but I’ve no bindings to consider so it’s not right or wrong, maybe just give it a go with your UNDEF on one light and see if it works and your happy with it.

I don’t think so but something might be possible using a MAPPINGS in some circumstances or with a custom widget in HABPanel.

When using the action (postUpdate(MyItem, NULL)) or the method call (MyItem.postUpdate(NULL))? I would expect the method to work but would not necessarily expect the action to work.

Probably the best policy. NULL is intended to indicate an Item is in an uninitialized state rather than to have a specific meaning like AJAR. Better to do what you suggest, use something like a Number or String Proxy Item to represent the state and leave the NULL to keep its existing meaning.

Both resulted in error when I tested:

[ERROR] [ntime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule ‘test rule…’: The argument ‘state’ must not be null or empty.

[ERROR] [ntime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule ‘test rule…’: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,org.eclipse.smarthome.core.types.Command) on instance: null

Gave me the impression someone was being defensive against it hence avoid.

Yes good reminder NULL is NULL and not a state to be reused. If it doesn’t feel right then it’s usually a good sign to do it properly.

1 Like

Just coming back to this as I’ve implemented some of my light control and have refactored it a bit since my suggestion above that I think achieves the same result but has less rules and coupling hence I think is simpler.

Some possible reasons for controlling the light, fed from different sensor data:
Front Door opened
Hall PIR opened
Security system - normally presence off and just simulating activity
Manual override
Alarm triggered

At the top level I have a Group Switch with AND(ON,OFF) so All ON is ON else OFF:

Group:Switch:AND(ON,OFF) grp_Landing_Lights_Proxy "Landing Lights Proxy [%s]" <light> (grp_House)

The proxy group is bound to my physical light switch so ultimately its state defines whether the light is ON or OFF. I’ve only put two sub items in to this main proxy group, an Auto switch:

Switch swt_Landing_Lights_Auto "Landing Lights Auto [%s]" <light> (grp_Switches, grp_Landing_Lights_Proxy)

For me the Auto item will be set ON 99% of the time. If your light is in a bedroom and you wanted to turn off the light this is the item you use to turn the light OFF. I expect I’ll use it for ‘alarm triggered’ conditions so I can flash the lights.

The second sub item of the proxy group is actually another Group Switch, this time OR based and ON if any ON else OFF:

Group:Switch:OR(ON,OFF) grp_Landing_Lights_OR "Landing Lights OR [%s]" <light> (grp_Landing_Lights_Proxy)

Previously I was chasing the state of the light to put it back on in cases where one of the activities had possibly also changed state. Now each activity based rule only deals with controlling its own switch state so I’ve got these switch items in the sub group:

Switch swt_Landing_Lights_PIR "Landing Lights PIR [%s]" <light> (grp_Switches, grp_Landing_Lights_OR)
Switch swt_Landing_Lights_Manual "Landing Lights Manual [%s]" <light> (grp_Switches, grp_Landing_Lights_OR)
Switch swt_Landing_Lights_Sec "Landing Lights Security [%s]" <light> (grp_Switches, grp_Landing_Lights_OR)

The PIR and security rules only deal with their appropriate switch item, they don’t care about anything else that is going on. I’ve put the Manual switch on my UI devices so people can turn ON the lights if they need to i.e. sitting reading when the PIR times out.

So although not technically a single Tri-State item it can meet the requirements:

ON - set Auto and Manual items ON
AUTO - set Auto ON and Manual OFF
OFF - set Auto OFF

you could also front your UI with a Tri-State widget that mapped it down to those settings.

Note: My lights are one way so binding to the Group is fine but if you have lights that feedback and bind to a Switch Item I guess you will need to make some changes. Maybe have another item outside of these groups which is bound to the light and some rules to sync them appropriately with the Manual item.

2 Likes