Hi all,
I have a question regarding the usage of Exec 2 Binding. Suppose I have a script that receives a command (“ON” or “OFF”), controls a device (turns it on or off) and returns the execution result - the actual state of the device (again “ON” or “OFF”). The device can go offline or some errors could occur, so the command may fail and after receiving an “ON” command the script could actually return an “OFF” value and vice versa. It would be great if I could create an openHAB configuration where:
a Switch changes it’s state when the user clicks on it;
the script gets called and the state of the Switch is passed to it as an argument (“ON” or “OFF”) (Exec input channel is used);
the script tries to turn on or off the the device and returns the result (“ON” or “OFF”) (I suppose Exec output channel must be used);
the state of the Switch is updated according to the state returned from the script.
So basically the user clicks/taps on a Switch an if an error occurs the state of the Switch will not change. If everything is fine the Switch will change it’s state and the user can be sure the command succeeded.
I know that periodic polling of the actual device state could be used but that is not desired for many reasons.
Create a proxy Item that represents your Light switch’s state to OH
Continue to use the Exec binding or use executeCommandLine in a rule to call your script, I’ll assume you continue to use the Exec binding
Rules that get triggered when the Proxy Item receives a command and when the Item linked to the output channel receives an update
rule "Proxy Item received command"
when
Item MySwitchProxy received command
then
MySwitchInput.sendCommand(receivedCommand) // set the argument to the script, I think this kicks off the script if not
MySwitch.sendCommand(ON) // trigger the script to run
end
rule "Process result from script"
when
Item MySwitchOutput received update
then
if(MySwitchOutput.state != MySwitchProxy.state) MySwitchProxy.postUpdate(MySwitchOutput.state)
end
If you use executeCommandLine you can do it all in one Rule
rule "Proxy Item received command"
when
Item MySwitchProxy received command
then
val result = executeCommandLine("/path/to/script " + receivedCommand, 1000)
if(result != MySwitchProxy.state.toString) MySwitchProxy.postUpdate(result)
end
Have you ever considered that adding such functionality to Exec 2 Binding would be very useful? I mean something like an input_output Channel. It could accept a command from an Item and return the result that could be applied back to the Item.
The binding is designed to provide the result in a separate channel on purpose. It would be very difficult to provide a solution that would be generic because most of the time what the script returns is not compatible with the Switch Item that triggered the script to run in the first place.
Here both item_1 and item_2 use the same input_output channel. item_1 provides input parameters to the command (script) and item_2 uses the output of the command (script).