OH3: HSBType sendCommand = Ambiguous feature call

  • openHABian 3.3.0 on rPi4

I am trying to set up my first colour light, using the example in the documentation.
Here the example from the docs (Rules | openHAB)

import java.awt.Color

rule "Test: a light"
    when
        Item test_new_stuff changed to ON
    then
        val newColor = new Color(100,20,50)
        Shed_KDL_Colour.sendCommand(new HSBType(newColor.toString))
end

I tried this variation based on forum posts; same result:

        val newColor = new Color(100,20,50)
        val HSBType hsb = new HSBType(newColor.toString)
        Shed_KDL_Colour.sendCommand(hsb)

vsCode gives me a wiggly line under sendCommand.

image

The log is even more cryptic:

2022-11-21 23:00:14.283 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'test.rules'
2022-11-21 23:00:23.742 [INFO ] [ab.core.model.script.testRules.01.01] - test light...
2022-11-21 23:00:23.805 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test-1' failed: Character array is missing "e" notation exponential mark. in test

What am I missing?

Did you try simply: Shed_KDL_Colour.sendCommand(
new HSBType( “100,20,50”))
Or: sendCommand(Shed_KDL_Colour, new HSBType(“100,20,50”))

Command is picky about what type of object you send; generally a string is ‘safe’ as it will try to parse it into the required type.
Shed_KDL_Colour.sendCommand("100,20,50")
or
Shed_KDL_Colour.sendCommand(hsb.toString)

1 Like

Thanks, this works…

I wonder, why all the circus with new HSBType and all, and when simply providing the RGB value to the sendCommand?!

Given this solution, I neither need import java.awt.Color.
Way simpler.

HSBType has been around since OH 1. It’s always been the type supported by Color Items. It’s not exactly new.

There are lots of ways to represent color. Depending on the context, RGB is often not the best. HSB is a good choice for lighting because it breaks out the three parts of the lighting in a more human perceivable way. Hue: the base color, Saturation: how strong/vibrant that color appears, Brightness: how much light the bulb actually emits. With HSB, for example, you can control the brightness without impacting the color where in RGB every change has to be translated into a new color value.

There are some useful helper methods on HSBType so there may come a point where you may need to create an HSBType anyway. Luckily, you can pass the HSB values as a String just like you have with that working command. You can also pass them separately as a DecimalType (must be between 0 and 360), and two PercentTypes, one for saturation and the other for brightness.

HSBType (openHAB Core 3.4.0-SNAPSHOT API) (note this link is there in the rules docs you linked to above as well).

What I don’t see is any support for the java.awt.Color class associated with HSBType so where ever you came across a forum post that used Color in this way, it’s wrong. But if you do happen to have an RGB, there is a fromRGB() static method that will convert that to an HSBType.

NOTE: the three values you are sending in that command are not RGB. They are HSB, a wholly different color coordinate system. If you are thinking that 100 is Red, 20 is Green, and 50 is Blue, you will be surprised. In HSB those coordinates are a sickly green.

image

(looks like the shag carpet I grew up with).

The HSB equivalent of RGB 100,20,50 would be a kind of maroon color:
image

and the coordinates would be 337.5, 80, 39.

1 Like

I don’t know, it’s your rule. If you wanted to manipulate the colour in some way beforehand, you would need to have a colour object, not a string object.
You can always convert that to string.

1 Like

We must have posted at the same… :slight_smile:

Well, I took the documented example.

new Color does not work without import java.awt.Color

image

However, this works:

import java.awt.Color

rule "Test: a light"
    when
        Item test_new_stuff changed to ON
    then
        val newColor = new Color(100,20,50)
        val HSBType hsb = new HSBType(newColor.toString)
        Shed_KDL_Colour.sendCommand(hsb.toString)
end

While we’re at it; I have searched on the forum on how to work with HSBType lights, and found different examples, which I have to modify with .toString to make these work.
Like the example above, where you think it is wrong using import java.awt.Color.

So I tried a different approach:

var Timer AutoLight = null

rule "Test: a light"
    when
        Item test_new_stuff changed to ON
    then
        var DecimalType hue = new DecimalType(120)     // 0-360; 0=red, 120=green, 240=blue, 360=red(again)
        var PercentType sat = new PercentType(80)      // 0-100
        var PercentType bright = new PercentType(50)   // 0-100
        var HSBType hsb = new HSBType(hue, sat, bright)
        Shed_KDL_Colour.sendCommand(hsb.toString)

        AutoLight = createTimer(now.plusSeconds(5), [|
            Shed_KDL_Colour.sendCommand(new PercentType(0).toString)
            AutoLight = null
        ])

end

It seems that to switch this light on and off, I send HSBTyype values, instead on off.
Though the Things channels tell me it can used to switch on|off, sendCommand(OFF) does not switch off this bulb.

Also, I am sending a new PercentType(0), which switches the light off.
How does it know it should reduce brightness and not saturation?
And why does my command need a cast .toString?

Also, using the rule above and having added Shed_KDL_Colour as a switch item to the sitemap allows me to switch on the light, but it does not update the switch to OFF once the time expires.

Such a light seems complicated.

Do I need to add switch item to the colour channel to get ON|OFF functionality?

It’s up to the binding what it does, if anything, with command OFF to turn it into something a real device can act on.

I don’t seem to follow…

This is the Zigbee binding, which discovered the Thing with these channels.

Do I need to add switch item to the colour channel to get ON|OFF functionality?
Or do I just send ‘0’ to switch it off?

I don’t know, we’re talking “how to configure Zigbee” now. People with the answers to that probably won’t look at thread about rules - I would suggest a new thread, separate issue.

This is probably about feedback from the Zigbee binding as well.

I’d suggest including a section of your events.log showing what happens to the Item(s), alongside the description…

There is a reason for asking for events
a) Not all Zigbee devices are equal
b) Zigbee binding vetoes the usual autoupdate internal guesswork
c) Combination of (a) and (b) leaves some Zigbee devices with poor feedback - this is visible by absence of update events

Thanks…

I figured it out, partially; the rule needed a test_new_stuff.postUpdate(OFF) for the switch. Little things; maybe too late for today :slight_smile:

But does it? java.awt.Color represents color as RGB. As my previous post demonstrated, HSB is a wholly different color coordinate system. It “works” for that specific Color in that it doesn’t throw an error, but it will give you the wrong color. If you had new Color(100, 200, 50) it would fail because you can’t have a saturation above 100 even though that’s a perfectly reasonable RGB.

If you’ve taken calculous and remember working with circles, it’s like the difference between working in degrees and radians. The numbers are different.

If you’re using toString to send the command anyway, why mess with HSBType in the first place? Just use Shed_KDL_Colour.sendCommand('120, 80, 50') and Shed_KDL_Colour.sendCommand(0) ( or Shed_KDL_Colour.sendCommand('0') or Shed_KDL_Colour.sendCommand(OFF) which are all equivalent).

You only need to mess with HSBType directly when you need to do conversions. For example:

    val hsb = HSBType.fromRGB(120, 80, 50) // converts the RGB coordinates to HSB
    Shed_KDL_Colour.sendCommand(hsb.toString)

That’s a bug in the binding then (or possibly a misconfiguration). A Color Item can be commanded like a Switch (ON/OFF), a Dimmer (PercentType), or a Color (HSBType).

Because when you send a single number as a command to a Color Item it treats it as if the Item were a Dimmer. That’s by design. If you want to change the saturation you have to send all three values.

I don’t know. I haven’t used Rules DLS in years and I don’t have Color Items in my system so don’t keep up with minor changes in how they behave. In all the other rules languages you always have to send it as a String.

Add a log statement to see if the problem is with the timer or the command itself.

No, that isn’t necessary. Something else is going wrong.

1 Like

:slight_smile: exactly my earlier point.
The example only worked with .toString.

And I have since tested the ON|OFF commands and they do work.


And for the rest of your post: thank you for the explanations; these are really helpful.