Any idea why I’m getting an Ambiguous Feature Call error for the below rule. And the rule does seem to function properly. Using OH 2.4 M7 and VS Code. Specifically the first two sendcommand functions are the problem, the third one does not give the error.
rule "Living Area Scene Load"
when
Item LivingScene_No received command
then
val timestamp = (ScriptServiceUtil.getItemRegistry.getItem("LivingScene_"+LivingScene_No.state)).state.toString
logInfo("Scenes","LivingScene_"+LivingScene_No.state + " started on " + timestamp)
LivingScene_HSB_Group.members.forEach(hsb | { hsb.sendCommand(hsb.historicState(parse(timestamp),"influxdb").state as HSBType) } )
LivingScene_DIM_Group.members.forEach[dmr | { dmr.sendCommand(dmr.historicState(parse(timestamp),"influxdb").state as PercentType) } ]
LivingScene_SW_Group.members.forEach(item | { item.sendCommand(item.historicState(parse(timestamp),"influxdb").state as OnOffType) } )
end
Sure seems like my issue relates to HSBType and PercentType in my statements. OnOffType is ok. Strange that the 3 statements actually do function but have the Ambiguous Feature Call, and any code after the 3 statements will not run (even a simple log entry as a test).
If you’re referring to the brackets on two of the three forEach statements, then yes those are corrected. I did comment everything out, and can log just fine without error.
It’s these two lines giving me the error:
LivingScene_HSB_Group.members.forEach[hsb| { hsb.sendCommand(hsb.historicState(parse(timestamp),"influxdb").state as HSBType) } ]
LivingScene_DIM_Group.members.forEach[dmr| { dmr.sendCommand(dmr.historicState(parse(timestamp),"influxdb").state as PercentType) } ]
and the entire rule:
rule "Living Area Scene Load"
when
Item LivingScene_No received command
then
val timestamp = (ScriptServiceUtil.getItemRegistry.getItem("LivingScene_"+LivingScene_No.state)).state.toString
logWarn("Scenes","LivingScene_"+LivingScene_No.state + " started on " + timestamp)
//logWarn("Scenes","Test LivingScene_"+LivingScene_No.state)
LivingScene_HSB_Group.members.forEach[hsb| { hsb.sendCommand(hsb.historicState(parse(timestamp),"influxdb").state as HSBType) } ]
LivingScene_DIM_Group.members.forEach[dmr| { dmr.sendCommand(dmr.historicState(parse(timestamp),"influxdb").state as PercentType) } ]
LivingScene_SW_Group.members.forEach[item| { item.sendCommand(item.historicState(parse(timestamp),"influxdb").state as OnOffType) } ]
end
I’m on the phone so don’t have my code handy.
Is it hsbtype or should it first be cast to item and then type?
Edit
If you print out those types, are they indeed not NULL?
i.e. The previous state
I just don’t understand types well enough I suppose. Nor do I know how to get the data to print, but I don’t think it’s NULL because, for example, the HSB data is properly passed to the lights in the group.
I suspect because the data is coming from the influxdb, and stored as an integer (I think) that is causing the issue here. I know the influxdb also stores on/off states as well, so that’s why the OnOffType is not giving me trouble.
I rewrote the code a bit to allow a log item to be created for the HSB Item. This logged correctly as:
HSB Item Data_92,88,0
Then I assigned that data to a variable (hsbItem). No errors there. Then tried to send that variable via send command, but getting the same Ambiguous error on the sendCommand statement. Code snippet below:
LivingScene_HSB_Group.members.forEach[hsb|
{
logWarn("Scenes","HSB Item Data_"+hsb.historicState(parse(timestamp),"influxdb").state as HSBType)
//this log works fine, I see data HSB Item Data_92,88,0 for example
var hsbItem = hsb.historicState(parse(timestamp),"influxdb").state as HSBType
//no errors above
hsb.sendCommand(hsbItem)
//Ambiguous feature call on this line
}
]
HSBType is also of type PercentType and OnOffType.
A Color Item can receive commands of type HSBType, PercentType, and OnOffType and there is a separate sendCommand and postUpdate method for each. So periodically the roles engine gets confused about which one you really mean to call because in this case there are three valid choices
That is what the “ambiguous function call” means.
By calling toString you are forcing it to use the method that takes a String therefore clearing the ambiguity.
Let’s take a simpler example with DecimalType. The type hierarchy of DecimalType is
Object
|
Number
|
DecimalType
The state of a Number Item is of type DecimalType. But DecimalType is also of type Number.
So, when I NumItem.sendCommand(MyItem.state as DecimalType) I’ll still get the ambiguous method call because DecimalType is also a Number and there is a sendCommand for both DecimalType and Number. Casting the state to DecimalType doesn’t help because both sendCommands are still valid. To clear the ambiguous error you would have to cast the state to Number instead of DecimalType.
The same is happening here with HSBType. HSBType is also a PercentType and an OnOffType. It looks something like:
Object
| |
PercentType OnOffType
\ /
HSBType
So even if you cast the state to HSBType, it is still a PercentType and an OnOffType too so it doesn’t clear the ambiguity.
If you cast the state to OnOffType or PercentType it would work though because there isn’t anything else up the chain of inheritance that matches a sendCommand on the Color Item. So your second line would work.
I almost always see this error with DecimalType but this is the first I’ve seen someone report the error with HSBtype.