It’s a subtle issue of type. When you call .state you get back an Object of type State. sendCommand requires a String, a Number, or a Command type Object. So you need to cast or convert that State Object into one of those in order for it to work as an argument to sendCommand.
By calling toString you are converting the State to a String. Other options could be:
MyOtherItem.sendCommand(MyItem.state as Number)
MyOtherItem.sendCommand(MyItem.state as Command) // NOTE: not all States are Commands and not all Commands are States, for example StringType is only a State, PLAY is only a Command
`sendCommand(MyOtherItem.name, MyItem.state.toString) // NOTE: the postUpdate and sendCommand actions only supports two Strings as arguments
With Number Items there is one gotcha. There is a method of sendCommand that accepts Number and another one that accepts DecimalType. For some reason, when you cast the state to DecimalType it will get confused and throw an ambiguous method call exception because a DecimalType is also of type Number. It doesn’t throw an exception when cast to Number though so I always recommend avoiding casting to DecimalType.
Finally, one more passing comment. dimmer is a Number. You cast Kitchen_StringLED.state to Number which is what dimmer is expecting. So why make the call to intValue? All it’s going to do is convert the state to a primitive int only to convert it back to a Number. Not only is it redundant, at least on OH 2, forcing variables to be a certain type unnecessarily can add huge amounts of time to the loading and parsing of .rules files. I have no expectation that this would change in OH 3. So avoid forcing stuff to be a type unless necessary and definitely avoid forcing stuff to be primitives unless absolutely necessary.
There is a lot of magic that the language does to make it kinda sorta typeless. When it works it’s great (i.e. when you can just call .state and it’s able to convert the State to what ever it needs to be in that context) but often times it can’t. For example logInfo("Test", "Some state " + MyItem.state) works because the "Some state " is a String so the language is smart enough to coerce MyItem.state to a String by calling toString for you. However, logInfo("Test", MyItem.state + " Some state") wont work because the first argument is a State/Number and it’s not smart enough to realize that if the second argument is a String so you want to use the String + operator, not the Number + operator.
So use the following rules to thumb.
By default don’t specify the type
When it doesn’t work cast it to Number (if you are in a calculations/comparison context) or call toString
Only ever convert a Number to a primitive when necessary and do so at the last moment (e.g. in calling now.plusSeconds((MyDelay.state as Number).intValue))
Thanks @rlkoshak as always for great explanation !
most probably some kind of leftofvers from the past when I created those rules… you know “if it ain’t broke, don’t fix it”
But I very often sadly do try to fix it for no good reason