Pushbutton for openhab2

My goal is to have a pushbutton that when clicked it turns a pin HIGH for 1 second, then LOW again. Just like clicking a real push-switch on a wall for 1 second

I managed to do the following:
at 1st click the pin goes HIGH and stays HIGH
at 2nd click the pin goes HIGH (or rather stays high) for 1 second then goes LOW
I think it’s a programming error, but I can’t see it.

home2.items:
Switch b1_virtual {autoupdate=“false”}
Switch b1_real {gpio=“pin:4 activelow:no”}

home2.sitemap:
sitemap home2 label="Main Menu lights test"
Frame label=“testlight1”{
Switch item=b1_virtual label=“Test Light 1” mappings=[ON=“Press”]
}
}

home2.rule:
var timer

rule B1VIRTUAL

when
Item b1_virtual received command ON
then
sendCommand(b1_real, ON)
if(b1_real.state==ON) {
timer = createTimer(now.plusSeconds(1)) [|
sendCommand(b1_real, OFF)
]
end

I am not at home and can´t reproduce your problem, but I guess your just to fast.

So the first sendCommand will create an event to switch the b1_real to ON. But you can´t assume that this will happen instantly. b1_real stays with UNDEF, NULL, OFF or whatever. Following that, the equatation will be false and skipped.

If you push the button the second time, the state is already set for b1_real and it will sendCommand again and the equatation will be true and the time will be created.

Maybe you can proof my assumption by adding an else to the if statement and push out the state to the logfile.

A few other methods to try instead of a timer. You can use the (relatively) new Expire binding. This allows you to set a property in the item configuration to automatically return the switch/sensor to off or null state after a designated time. Or you can use thread:sleep instead of a timer. This tells the rule to “pause” for the designated time before proceeding. I use this for my garage door relay. Turn relay on, sleep for 2 seconds, and then turn relay off.

Here is a degub log:

1st click:
15:49:01.280 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘b1_virtual’ received command ON
15:49:01.300 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘b1_real’ received command ON
15:49:01.312 [INFO ] [marthome.event.ItemStateChangedEvent] - b1_real changed from OFF to ON

2nd click:
15:49:11.231 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘b1_virtual’ received command ON
15:49:11.251 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘b1_real’ received command ON
15:49:12.260 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘b1_real’ received command OFF
15:49:12.271 [INFO ] [marthome.event.ItemStateChangedEvent] - b1_real changed from ON to OFF

I think patrickse is right, but I still do not understand why b1_real does not turn ON instantly. How should I push the state to the log file?

RHINESEL: using sleep could do the trick but I would rather try the expire binding, seems smart. I have to research it

I guess it´s not instantly changing because it´s non blocking event driven. So it pushes the message to event bus and all the subcriber to this bus will retrieve the message and perform the action.

This will happen async and you can´t work with this in a syncronous way.

I am not sure, but may be this can help you. This rule is using some locking mechanism to prevent race conditions. Program Rollershutter with GUI

I did RHINESEL’s trick and it works:

var timer
rule B1VIRTUAL

when
Item b1_virtual received command ON
then
sendCommand(b1_real, ON)
Thread::sleep(1000)
sendCommand(b1_real, OFF)
sendCommand(b1_virtual, OFF)

end

This is the log now:
17:55:45.107 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘b1_virtual’ received command ON
17:55:45.121 [INFO ] [marthome.event.ItemStateChangedEvent] - b1_virtual changed from OFF to ON
17:55:45.131 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘b1_real’ received command ON
17:55:45.139 [INFO ] [marthome.event.ItemStateChangedEvent] - b1_real changed from OFF to ON
17:55:48.137 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘b1_real’ received command OFF
17:55:48.143 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘b1_virtual’ received command OFF
17:55:48.153 [INFO ] [marthome.event.ItemStateChangedEvent] - b1_real changed from ON to OFF
17:55:48.160 [INFO ] [marthome.event.ItemStateChangedEvent] - b1_virtual changed from ON to OFF

I guess 1 second sleep is enough for the event to be retrieved and the action performed
I will look into the expire binding and post an updated rule, maybe it helps others in the future too.

later edit: the switch status did not turned properly red/green until a openhab restart