OH2: Switch-triggered rule not working

I’m currently using the 2.0 exec binding to monitor the state of a device (in this case a hs100 outlet) and it works fine:

Thing exec:command:hs100status "TP-LINK HS100 STATUS" [ command="/etc/openhab2/services/linuxscripts/tp-link-hs100-smartplug/hs100.sh 9999 check", interval=60, timeout=15]
Switch tplinkhs100_status "Outlet State" {channel="exec:command:hs100status:exit"}

However, I’m having trouble creating a rule that is fired when you manually change the state of the switch through a UI.

rule OutletUpdated
    Item tplinkhs100_status received update
    logInfo("Test", "update triggered with status update " + tplinkhs100_status.state.toString())

rule OutletStateChanged
	Item tplinkhs100_status changed
    logInfo("Test", "outlet state changed to " + tplinkhs100_status.state.toString())

rule OutletToggled
    Item tplinkhs100_status received command
    logInfo("Test", "toggle triggered with command " + tplinkhs100_status.state.toString())
    executeCommandLine("/etc/openhab2/services/linuxscripts/tp-link-hs100-smartplug/hs100.sh 9999 " + tplinkhs100_status.state.toString().toLowerCase())

The OutletUpdated rule fires when the the Exec Thing fires its periodic update. It does not fire when the Switch is manually toggled.

The OutletStateChanged rule fires only when the Exec Thing fires its periodic update and the state has changed from OFF to ON or ON to OFF. It does not fire when the Switch is manually toggled.

The OutletToggled rule never fires at all.

I would expect the command rule to fire when the Switch is toggled in the UI. Is the channel binding somehow preventing the commands from being sent or something? Beyond making a full-fledged Binding for the outlet, what is the recommended approach to wiring up Switches with Exec 2.0 bindings?

When you do toggle the Switch through the sitemap does the OutletUpdated rule fire or do none of the rules fire?

In any case, I think you need to add the run channel to the Switch in addition to the exit channel if you want to script to actually execute when you toggle the switch from the sitemap. And I’m not sure it makes sense to use the exit channel with a Switch anyway since that channel returns the exit value of the command as a Number. There might be some error that is preventing this from working like you would expect.

No rules fire when toggling the switch through the sitemap. Interestingly,
I was using HABmin’s sitemap to do the toggling. When viewing the switch
through PaperUI, it is read-only. My guess is that since the binding
channel is an output-only channel, OH2 disables the command output of the
bound item.

The run channel would not be appropriate in this case, since the Thing that
the Switch is bound to is a script that gets the current state of the
real-world object periodically. The OH1 Item definition is more convenient
in this way, since a Switch can have status AND command-based channels
hooked up.

Perhaps the solution is to use the Switch currently bound to exit as a
dummy that fires a rule for updating another Switch that is bound to the
run event of the set Exec. I’ll try that out tonight and see how it works.
I was hoping that I was just overlooking some feature for wiring up a
status+update Switch without jumping through hoops.

I may (or may not) have gained some new insight into how the exec binding works based on another thread.

I think you can’t do everything on one Item any longer.

If you need to pass command line arguments, you create a separate String Item mapped to the input channel and whatever that Item is set to gets passed to the command as an argument.

If you care about the result you need a separate String Item mapped to the output channel.

If you care about the command line’s return value you need a separate Number Item mapped to the exit channel.

And if you want to execute the command yourself you need a separate Switch Item mapped to the run channel.

So, if you had a command that took an argument you would:

  1. postUpdate the argument to the Input Item
  2. sendCommand ON to the Switch
  3. check the Exit and/or Output Items for the results

At least that is my going theory right now. I don’t (and can’t since I run in Docker) use this binding to test things out myself.

After considering all the options (run channels, String input channels with the autorun checkbox on, etc) I decided that this was the most elegant:

Switch tplinkhs100_status "Outlet State" {channel="exec:command:hs100status:exit"} 
Switch tplinkhs100_switch "Set Outlet State" (outlets)

The first Switch is just a hidden item that is used to fire the update rule for the second Switch. The second switch has a rule to send a command. Note that the first item could easily have been a Number or a String bound to an output channel (if that suites you better).

And the rules:

rule OutletReportedStateChange
    Item tplinkhs100_status changed
    logInfo("Test", "Detected outlet state change. Updating switch to: " + tplinkhs100_status.state.toString())

rule ChangeOutletState
    Item tplinkhs100_switch received command
    logInfo("Test", "Received state change request. Updating to: " + tplinkhs100_switch.state.toString())
    executeCommandLine("/etc/openhab2/services/linuxscripts/tp-link-hs100-smartplug/hs100.sh 9999 " + tplinkhs100_switch.state.toString().toLowerCase())

The biggest flaw with this setup is that the useful Item (the channel-free switch) does not appear in PaperUI’s default control view, nor in HABmin’s generated Sitemap. I suspect that they explicitly only show Items explicitly attached to Things. The Switch must be added as part of a custom sitemap as a result. However, the Switch updates properly when an external event causes a state change and triggers event changes, so I’m happy.

I prefer the rule execution over binding a Switch directly to a setter Exec binding because the binding’s channels don’t really fit well. Maybe in the future the Exec 2.0 binding will get better or we’ll see a built-in function for wiring up Switches this way.