How to configure a rule condition on color state in OH3 - Web-Interface?

I do have a color item which I am using to select a color for an LED stripe.
I want to define I rule now which acts at a certain color valu, currently I want to act if RGB is (0,0,0) - means if the LEDs are off. But how do I need to do this in the rule configuration?

As I don’t know the syntax to define a color in the rule I tried to use state = OFF but even this did not trigger my rule.

Any suggestion how to proceed?

The general way to proceed here is to look at the logs and see what those show for the item state. What’s going on here is that the UI doesn’t know about the actual OH states, it’s only going to work from string because that is what are stored in the YAML configuration files that you are creating with the UI and that is what is passed to and from the api that the UI is using. Fortunately, every item state can be converted to a string (for some of these, such as an image item it’s a long awkward string). One of the easiest ways to see what the string version of an item state looks like is to check the logs for when that item changes. Once you see how the OH formats the state for the logs you can just replicate that in the UI dialog.

*The advanced solution is to look at what is returned by the item call in the api explorer; that is also the stringified version of the state.

Thanks for the hint, another thing learnd on OH. Using the API explorer did the job for me

One or two additional question came up, in the log or in the api explorer I see the value is “0,0,0” if the LEDs are off.

  • Is thes the RGB value or the HSB or any other color coding convention?
  • Is it possible to convert the values from the one format to the other within the rules definition? If yes, what would be the syntax for it?

See

Rather misleadingly it mentions RGB, but you’ll note that the Item type state and commands are actually given in HSB.

Sure, if you mean within system hosted rules.

For example, in a DSL rule you can do
myColorItem.getStateAs(OnOffType)

If you’re talking about Web UI as per header, probably, but not with native methods.

What are you trying to do, what have you got so far?

Thanks for sharing the links and your comments.

As also written in a different post (How to delay (the sending of) a mqtt request?) I am trying to combine 2 things into one item with some rules.

My RGB LED strip is controlled by an esp32 and as the power supply has a high standby power consumption I want to use a ikea switch before the power supply.

  • If I now change the color of the RGB Item I want a rule to be executed and switch on the switch.
  • If I switch off the LEDs by setting them to “black” RGB(0,0,0) the switch shall be turned off.

Currently I am using the following rules (code from code-section in WEB-UI)

triggers:
  - id: "1"
    configuration:
      itemName: ESP32KitchenLeft_Color
    type: core.ItemStateChangeTrigger
conditions:
  - inputs: {}
    id: "4"
    configuration:
      itemName: ESP32KitchenLeft_Color
      state: 0,0,0
      operator: "!="
    type: core.ItemStateCondition
actions:
  - inputs: {}
    id: "2"
    configuration:
      itemName: NetzteilKuche_Betrieb
      command: ON
    type: core.ItemCommandAction
triggers:
  - id: "1"
    configuration:
      itemName: ESP32KitchenLeft_Color
    type: core.ItemStateChangeTrigger
conditions:
  - inputs: {}
    id: "3"
    configuration:
      itemName: ESP32KitchenLeft_Color
      state: 0,0,0
      operator: =
    type: core.ItemStateCondition
actions:
  - inputs: {}
    id: "2"
    configuration:
      itemName: NetzteilKuche_Betrieb
      command: OFF
    type: core.ItemCommandAction

But with those the switch is not actuated as expected.
Sometimes

  • if I switch the color item from HSB(0,0,0) to HSB(0,0,100) the switch is turned on
  • if I switch the color item from HSB(0,0,0) to HSB(0,100,0) the switch is turned on and then off again

But in other times it does not turn on/off the switch at all.

So I am a bit lost how to trace down the issue now in OH.

You’ll probably want to start by looking in your events.log to see how your Items state changes go when sent nonsense commands.

Thanks for you fast response.
In the meantime I did went through the logs and it turned out that my rule is not triggered every time.
The state of the item is not updated all the time

  1. If I change the color via the GUI as my item is a MQTT channel with “MQTT State Topic” and “MQTT Command Topic”.
  2. As the ESP is not yet online if I change the color in the GUI I do not get a response.
  3. Therefore my rule was not triggered.
  4. I needed to change my rule to react on “an item receives a command” instead of “an item state changes”
  5. I assume that in cases where it was working the power supply still had some capacity which kept the esp alive and therefore the state values where updated.

But now I have the problem that if I change my color via GUI to e.g. HSB(0,100,0) the switch is triggered to be activated, but this is not needed as B = 0 and therefore all LEDs would still be off.

So how would I need to write this into the rule condition to only activate the switch if the LEDs would realy be turned on? - Can I somehow convert the HSB value into RGB and then compare it against “0,0,0”?

When you send commands to an Item linked to a “broken” channel, autoupdate predicts that the command will fail and so does not update Item state.
For testing your rules, you can set individual Item autoupdate to "true’ which will override that and force the update.

I’m sure you could. Pointless, just to find out if it is “on”.
Why not use .getStateAs(OnOffType)?

Maybe I am a little lost here and it might be a dumb question but how would I do that in the WEB-UI?
In the Web-Interface I can only define the value to compare against, but how would I tell the rule to get the State as OnOffType and compare it against “ON”?

That I don’t know, but you can trigger on any change and control the activity with if() in the script section of a rule.

You’re getting bogged down trying to create precise triggers, so don’t. Trigger off generalities and use the flexibility of scripting to achieve your ends.

Ohh okay, I see.

So it would be a approach with gui AND scripting not only within the GUI.
Understood, so I will look into writing scripts in OH, haven’t done that yet.

1 Like

Okay, looks like the scripting is quite powerfull and I will give it a try for my usecase. Unfortunatelly I am stuck at the next problem now :slight_smile:
.getStateAs(OnOffType) will only work if I the ESP is on as only then the state is updated (see above discussion)

How would I do that?

Or is there a way to also read the “GUI” values (kind of the requested values) of the item and not the state?

Autoupdate is a configurable option on each individual Item. You edit your Item.

Fuller background for context -

It’s very important to understand the distinction between commands (“do something”) and state (“it’s like this”).
There may no relation between commands and states, e.g. command OFF to a Dimmer will usually result in state 0%.
Users poking UI buttons results in commands.

Think carefully about which you want to look at in rules, seeing as they are cause and effect. It’s your choice for triggering, then within the rule you can examine either.

So if I would like to react on the command based on the content of the command is there a similar function like .getStateAs(OnOffType) for a command? Or would I need to manualy split the comand color code into its 3 parts and then compare the B value against 0?

I now ended up with a rule which is triggered on a command beeing received and which executes a script:

triggers:
  - id: "3"
    configuration:
      itemName: ESP32KitchenLeft_Color
    type: core.ItemCommandTrigger
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >-
        logInfo("Rule", "Received: " + receivedCommand.toString);


        var array = receivedCommand.toString.split(',');


        //Check if on or of is requested

        if ((receivedCommand == ON) && (NetzteilKuche_Betrieb.state == OFF)) {
          NetzteilKuche_Betrieb.sendCommand(ON);
          logInfo("Rule", "Item 'NetzteilKuche_Betrieb' will switch on");
        } else if ((receivedCommand == OFF) && (NetzteilKuche_Betrieb.state == ON)) {
            NetzteilKuche_Betrieb.sendCommand(OFF);
            logInfo("Rule", "Item 'NetzteilKuche_Betrieb' will switch off");
        //if no on or off is requested we can assume that it is a color code which is requested as HSB and we evaluate B to determine if the leds need to be turned on or off

        } else {
          if ((array.get(2) != "0") && (NetzteilKuche_Betrieb.state == OFF))  {
            NetzteilKuche_Betrieb.sendCommand(ON);
            logInfo("Rule", "Item 'NetzteilKuche_Betrieb' will switch on");
          }
          if ((array.get(2) == "0") && (NetzteilKuche_Betrieb.state == ON)) {
            NetzteilKuche_Betrieb.sendCommand(OFF);
            logInfo("Rule", "Item 'NetzteilKuche_Betrieb' will switch off");
          }
        }
    type: script.ScriptAction

This solves my problem for now, but it does not look very elegant. Maybe someone has a hint for me how to to it in a more OH-Style-Way.

It’s a little fiddly, because receivedCommand can be of various types - OFF, INCREASE, “52”, “34,56,78”, REFRESH etc. are all valid things to command a Color type with, and they’re all different object types with different methods.

You can test what type it actually is
if (receivedCommand instanceof HSBType) { ...
but I don’t know a way to directly use anything like getStateAs() on the non-state command.
HSBType does have a “shortcut” .getBrightness() which will do some of the work.

Here’s a possible DSL approach that should deal with any command you’re likely to get and work out if commanded off or not.

    var CommandOff = false
    if (receivedCommand instanceof HSBType && (receivedCommand as HSBType).getBrightness.intValue == 0) { 
        CommandOff = true
    } else if (receivedCommand instanceof PercentType && (receivedCommand as PercentType).intValue == 0) {
        CommandOff = true
    } else if (receivedCommand instanceof OnOffType && receivedCommand == OFF) {
        CommandOff = true
    } else {
        logInfo("test", "ignoring command " + receivedCommand.toString)
    }
    logInfo("test", "command 'off' is " + CommandOff.toString)

It’ll be very similar to do this in javascript.

1 Like

Nice piece of code, this looks much more elegant, I will try to make use of it in my project.

Thanks for your support!