Here’s a lambda to send a command or update to an item, but only if the command/state being sent is different than the item’s current state. The lucid JSR223-Jython utils.py module (@RRoe) does some checks to make sure the item is compatible with what is being sent. I added that in too, but in a more robust way that checks all allowed State and Command types, just as is done when using sendCommand and postUpdate. For example, you can’t send a OFF to a DecimalType item. This version works in the Rules DSL and includes both sendCommand and postUpdate.
Usage:
You’ll need to pass an item, a string, and a boolean (true for SendCommand and False for postUpdate). I’ve played with it a little… please let me know if you find any issues!
checkFirst.apply(Virtual_Switch_1, "ON", false)
If you combine it with this, you can use a string name, like…
checkFirst.apply(ScriptServiceUtil.getItemRegistry.getItem("Virtual_Switch_1"), "ON", false)
Lambda
Put all of this at the top of your rules file, under any other imports.
import org.eclipse.xtext.xbase.lib.Functions
import org.eclipse.smarthome.core.types.State
import org.eclipse.smarthome.core.types.Command
import org.eclipse.smarthome.core.types.TypeParser
val Functions$Function3<GenericItem, String, Boolean, Boolean> checkFirst = [
GenericItem item,
String newValue,
Boolean SendCommand |
if (SendCommand) {
val Command parsedCommand = TypeParser.parseCommand(item.acceptedCommandTypes,newValue)
if (parsedCommand !== null) {
if (item.state.toString != newValue) {
item.sendCommand(newValue)
logDebug("Rules", "checkFirst: {}: Sent Command [{}]",item.name,newValue)
}
else {
logDebug("Rules", "checkFirst: {}: Not sending Command [{}] because it matches current state",item.name,newValue)
}
}
else {
logWarn("Rules", "checkFirst: {}: Cannot convert [{}] to an accepted Command type: [{}]",item.name,newValue,item.acceptedCommandTypes)
}
}
else {
var State parsedState = TypeParser.parseState(item.acceptedDataTypes,newValue)
if (parsedState !== null) {
if (item.state.toString != newValue) {
item.postUpdate(newValue)
logDebug("Rules", "checkFirst: {}: Sent Update [{}]",item.name,newValue)
}
else {
logDebug("Rules", "checkFirst: {}: Not sending Update [{}] because it matches current state",item.name,newValue)
}
}
else {
logWarn("Rules", "checkFirst: {}: Cannot convert [{}] to an accepted State type: [{}]",item.name,newValue,item.acceptedDataTypes)
}
}
true
]