Help with a switch rule

Hi guys,

I need a bit of help with a rule. I have a garage door switch that has to be a momentary push button type. I use an aeotec nano switch and I want to configure it to turn itself off any time it’s turned on to get the effect of a momentary push switch. The problem is, if you leave the switch in the on state, then the normal manual switch no longer does anything, since it needs to be first in the off state. The rule I wrote was the following:

rule “GarageDoor”
when
Item Garage_Door changed
then
logInfo(“My switch rule”, "Garage_Door changed state to {} ", Garage_Door.state)
if ((Garage_Door.state == ON)) {
sendCommand(Garage_Door, OFF)
}
end

The problem is, after a restart of openhab2, it works the first time I trigger it, but all subsequent times it just stays stuck in the on position. The odd thing though, is that the log claims it has switched back to OFF. My log says:

2017-07-26 08:36:25.195 [INFO ] [marthome.model.script.My switch rule] - Garage_Door changed state to ON
2017-07-26 08:36:25.232 [INFO ] [marthome.model.script.My switch rule] - Garage_Door changed state to OFF
2017-07-26 08:36:36.020 [INFO ] [marthome.model.script.My switch rule] - Garage_Door changed state to ON
2017-07-26 08:36:36.059 [INFO ] [marthome.model.script.My switch rule] - Garage_Door changed state to OFF
2017-07-26 08:37:30.198 [INFO ] [marthome.model.script.My switch rule] - Garage_Door changed state to ON
2017-07-26 08:37:30.242 [INFO ] [marthome.model.script.My switch rule] - Garage_Door changed state to OFF
2017-07-26 08:38:19.132 [INFO ] [marthome.model.script.My switch rule] - Garage_Door changed state to ON
2017-07-26 08:38:19.160 [INFO ] [marthome.model.script.My switch rule] - Garage_Door changed state to OFF

It seems that somehow the nano switch is getting confused. Does anyone know how to get around this?

I changed the rule slightly to:

rule "GarageDoor"
when
Item Garage_Door changed from OFF to ON
then
logInfo(“Garage Door Swtch Rule”, "Garage_Door changed state to {} ", Garage_Door.state)
if ((Garage_Door.state == ON)) {
logInfo(“Garage Door Switch Rule”, "Garage_Door should be ON, actual state is {} ", Garage_Door.state)
sendCommand(Garage_Door, OFF)
while(Garage_Door.state == ON) {
logInfo(“Garage Door Switch Rule”, "Garage_Door should be OFF, actual state is {} ", Garage_Door.state)
}
}
end

It appears so far to work. I’m wondering, are these rules re-entrant or not. What I"m not sure about yet, though, is how accurately the Item is reflecting the actual state of the switch. I’ll try this for a while and see if it doesn’t lock up in the ON position anymore. I’ll keep you posted.

Reading to log in your inital post it looks as if you switched to ON every minute and the rule immidiatly switched back to “OFF”. What makes you think the switch got confused, maybe the Display on a GUI? Did you try to refresh this display?

On your second post:

[quote=“furryboffin, post:2, topic:32251”]
are these rules re-entrant or not.
[/Quote]
This rule doesn’t have a reentrant-lock, so it could be run several times, in fact by changing the Switch the rule calls itself again! However it does do anything, besides printing a logInfo, only if the .state is “ON”. IMHO a reentrant-lock isn’t needed.

How are you determining that the switch is stuck in the ON position?

I suspect that you managed to insert just enough of a delay to cause the OFF command to be received by the nano switch after the built in debounce period. When you press a physical button, the hardware will ignore subsequent changes in the state of the button for a period of time (hundred milliseconds or so depending on the physical characteristics of the button) so that signals caused by the button bouncing around after being pressed do not cause on/off signals from the button.

In your original rule you have no delay so the OFF command is sent out, according to the logs, 30 milliseconds after the ON command is received. This could easily have been received by the nano switch during its debounce period.

Go back to the original and see if just adding a Thread::sleep(100) fixes the problem.

Rules execute in parallel, one thread per event. Without putting in a lock as opus describes, if Garage_Door changes before the GarageDoor rule finishes, a new copy of the GarageDoor rule will start executing. It will not wait for the first instance to finish.

Hi, thanks for your observations. The reason I know the actual state of the switch gets stuck in on is that I stuck a meter on it and I could see the switch is closed.

Hi Rich,

Thanks for the explanation. That totally explains everything I needed to know. I think you’re probably right with the debounce circuit. I did know about this in the past, but I totally forgot this time. Let me try your suggestion with the delay and I’ll let you know if that’s enough to cure it.

Thanks again.

Indeed, that works. It must have been the debounce.

This does expose a weakness in openhab though. Even though the switch itself didn’t change state because of the debounce, the Item representing the switch state did change to OFF. That left the system in a weird state. Is there a way to have the switch periodically remind the item what state it’s in to avoid this? Or require a callback from the thing to the Item after a state change request to inform of success or failure of state change?

Actually, it is a weakness in the technology you are using. Not all technologies or devices in a technology immediately or ever report back to OH when the physical device changes state. For example, there are many Zwave switches that do not report back to OH when the user physically toggles the Switch. It is only when the Zwave binding triggers a poll (once per hour I think) that OH will have a chance to discover the switch changed states.

It has to be built into the technology you are using. For those technologies that support this the OH bindings implement it. For the rest, you need to figure out the state some other way (e.g. external sensors that report to OH).

Your particular case is somewhat of an edge case because what really occurred was akin to a failure. Even if the switch and technology did support immediately reporting (which I think it does based on what you described) while it is in the debounce period it doesn’t even know that it received the OFF command so it wouldn’t know that it needs to report the fact that it is still ON because it already just reported that it is ON.

I think the main take away here is that if you are dealing with sending commands to physical devices, always make sure there is at least 100 milliseconds between commands. Not only will think help you avoid your specific problem but for some relays and such switching them on and off too rapidly will break the device.

Thanks for the explanation… I’m learning all the time. That all seems completely logical.

Now, onto the next challenge. Try to get the HomeKit Addon working so I Can control my lights from siri… This may require a new post.