I like to mention that Rules DSL is probably the least good rules option in OH these days. It doesn’t support the full OH API. Being able to call another rule is only one area where it’s deficient. It has a half assed type system which leads to so many troubles (including the problem you are experiencing right now, see below) and odd behaviors. And it lacks a lot of standard programming features.
If you are ever looking into possibly moving off of Rules DSL (which I highly recommend) you would do well not to wait. As we progress Rules DSL has less and less to recommend it and is falling further and further behind.
Note, I never recommend converting your existing rules to Rules DSL. Only that you start to learn a bit about the other options and do new development on something else. Blockly is a great choice if you are not already a programmer.
Now for the error…
No, quite the opposite. What that error is saying is that it wants a java.lang.Number
but was unable to convert OFF
into that. Or more likely it’s having trouble converting OFF
to an org.openhab.core.types.Type
. Why does it expect a Type and a Number? Why, if my hunch is right, is it failing to convert OFF
to a Type
? Sometimes Rules DSL just can’t figure out types on it’s own.
However, one thing does stand out to me. You’ve set the type of the HashMap as <String, State>
. But you cannnot sendCommand
with a State
. You can only sendCommand
with a String
or
Command.
OFFhappens to be both a
Stateand a
Commandand in a normal language it would be able to figure that out and this would work. But Rules DSL only looks *up* the class hierarchy and never down and as far as it's concernted it has a
StateObject. It never looks down to see it has an
OnOffTypewhich is a
Commandwhich it can use in a
sendCommand` method call.
Try changing the type from State
to Command
or, even better from a simplicity perspective, just use Strings.
val HashMap<String, String> itemsToSet = newHashMap(
"Steckdosen_Kueche_Eierkocher" -> "OFF"
)
itemsToSet.forEachp itemName, value |
val item = ScriptServiceUtil.getItemRegistry.getItem(itemName)
if (item.state.toString != value) item.sendCommand(value)
]
For another example on the forum, in JS Scripting the above would look something like:
var itemsToSet = { 'Steckdosen_Kueche_Eierkocher': 'OFF' };
for(let itemName in itemsToSet) {
let item = items[itemName];
let cmd = itemsToSet[itemName];
if(item.state != cmd) item.sendCommand(cmd);
}
But that’s just one possible approach. You could use Item Metadata to store the value with the Item instead of hard coding it into a rule. Then you can do something like this:
items.getItems().filter( i => i.getMetadata("initItem") !== null)
.forEach( i => i.sendCommandIfDifferent(i.getMetadata("initItem").value)
The above gets all the Item with initItem
metadata and commands the Item to the value of that metadata if the Item’s state is different from that value.
In a text based .items file you’d add initItem="OFF"
to those Items you want to work with this code.