Failing to set custom color

I have tried to setup the following rule to change my light according to the state of my TV:

var DecimalType blue = new DecimalType(240) // 0-360; 0=red, 120=green, 240=blue, 360=red(again)
var PercentType sat_low = new PercentType(50) // 0-100
var PercentType dimmed = new PercentType(30) // 0-100
var HSBType tv = new HSBType(blue,sat_low,dimmed)

var PercentType warm = new PercentType(25) // 0-100

var PercentType max = new PercentType(100) // 0-100

// Change light according to TV state
rule "Light according to TV state"
when
	Item Fernseher received update
then
	if (Fernseher.state == ON) {
		sendCommand(YeelightFarbe, tv)
		sendCommand(YeelightHelligkeit, dimmed)
	}
	if (Fernseher.state == OFF) {
        sendCommand(YeelightFarbtemperatur, warm)
		sendCommand(YeelightHelligkeit, max)
	}
end

Unfortunately I am not able to use

sendCommand(YeelightFarbe, tv)

while

sendCommand(YeelightFarbe, HSBType::BLUE)

works.

The relevant log:

2017-07-18 18:24:23.018 [WARN ] [me.internal.engine.RuleContextHelper] - Variable 'tv' on rule file 'openhab.rules' cannot be initialized with value 'org.eclipse.xtext.xbase.impl.XConstructorCallImplCustom@6bbeba (invalidFeatureIssueCode: null, validFeature: false, explicitConstructorCall: true, anonymousClassConstructorCall: false)': null
2017-07-18 18:24:34.658 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Light according to TV state': The argument 'command' must not be null or empty.

I hope, someone can help.

Use

YeelightFarbe.sendCommand(tv)

or

sendCommand(YeelightFarbe, tv.toString)

I highly recommend using the first approach everywhere as it avoids this sort of problem.

The second approach, using the sendCommand Action, only supports Strings. Sometimes the Rules Language is smart enough to convert what is passed to it into a String on its own but often it fails. When you use the sendCommand method on the Item, the Rules Language is able to be smart enough to know that an HSBType is valid for YeelightFarbe.

Thank you for the fast reply. Unfortunately both commands did not work.

Here is the log:

“YeelightFarbe.sendCommand(tv)”:

2017-07-18 20:18:28.457 [WARN ] [me.internal.engine.RuleContextHelper] - Variable 'tv' on rule file 'openhab.rules' cannot be initialized with value 'org.eclipse.xtext.xbase.impl.XConstructorCallImplCustom@fa4be8 (invalidFeatureIssueCode: null, validFeature: false, explicitConstructorCall: true, anonymousClassConstructorCall: false)': null

“sendCommand(YeelightFarbe, tv.toString)”:

2017-07-18 20:19:27.194 [WARN ] [me.internal.engine.RuleContextHelper] - Variable 'tv' on rule file 'openhab.rules' cannot be initialized with value 'org.eclipse.xtext.xbase.impl.XConstructorCallImplCustom@582aa7 (invalidFeatureIssueCode: null, validFeature: false, explicitConstructorCall: true, anonymousClassConstructorCall: false)': null
2017-07-18 20:19:27.210 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Light according to TV state': cannot invoke method public java.lang.String org.eclipse.smarthome.core.library.types.HSBType.toString() on null

Besides: I got the part of the code from http://docs.openhab.org/addons/bindings/hue1/readme.html#rules where

var DecimalType hue = new DecimalType(240) // 0-360; 0=red, 120=green, 240=blue, 360=red(again)
var PercentType sat = new PercentType(100) // 0-100
var PercentType bright = new PercentType(100) // 0-100
var HSBType light = new HSBType(hue,sat,bright)
sendCommand(Light_GF_Lounge_C, light)

is used. Is the example code there right and only does not work in my case or should this example be updated?

I don’t do anything with color so can’t help any further with this error.

Hi,

As per the logs, I think the problem is with the tv variable, the parameters are wrong (try BLUE, instead of blue). If you understand code, take a look here.

Best regards,
George

I don’t think that will work. The global var “blue” is defined before “tv” is being defined so the lower case “blue” should be fine. He is not trying to use static BLUE from the RGB class or anything like that.

He is also using code verbatim from the Hue binding docs so something weird is going on.

Might not work indeed! Why then the throw from the the Constructor call?

I might be wrong!

@rlkoshak Thanks anyway for your assistance.

@george.erhan I don’t think this is the reason. I want to use this constructor:

public HSBType(DecimalType h, PercentType s, PercentType b) {
        this.hue = h.toBigDecimal();
        this.saturation = s.toBigDecimal();
        this.value = b.toBigDecimal();
}

for the required arguments I use the variables I create above (blue, sat_low and dimmed). Using “BLUE” would not be the variable “blue” I created, right?

What I can think of:

  • I need to import the HSBType class
  • The declaration of the variable “tv” is wrong

Assuming you are on OH 2 it is already imported.

To my eyes it looks OK but clearly something is wrong.

Yes, I am on OH2.

Right, but as @rlkoshak already said it does not matter!
You do not need to import.
Can you try percentage in the form of e.g. 0.5, instead of 50? I again might be wrong, but still I think the parameters are not “acceptable”!

I just tried to use “BLUE” and got a different error and also the form of “0.5” did not work.

Interesting:

var HSBType tv = new HSBType(new DecimalType(240),new PercentType(50),new PercentType(30))

works!

Then I think there is a problem with the xbase interpreter (or whatever calls are done by the rule engine)!
Thank you for trying, I will file an issue!

best regards,
George

Alright, thanks.

Hmmmm.

OK, so the example code in the Hue Binding is written assuming all the vars and the sendCommand are within one Rule. So as it was written there it works.

But you are making the variables be global vars. Perhaps the interpreter cannot access other global vars to define a global var. That would make sense of the error and the behavior and how the example code in the docs can work.

What happens if you use val instead of var? Since these are constants you should be using val anyway.

This may point to a limitation of the interpreter or be a side effect on how it parses and loads the global vars and vals. The same reason why there is no context or access to global vars and vals from within a globally defined lambda could be the root of the same limitation:

Global vars and vals do not have access to each other.

You are probably right. Changing everything to val did not help, but creating the HSBType inside of the rule works.
It is not ideal, though, since then I can only use it inside of this rule.

So, assuming you only use tv in your rules and not hue, sat, or bright anywhere else, just define tv on one line and eliminate the intermediate vals:

val HSBType light = new HSBType(new DecimalType(240), new PercentType(100), new PercentType(100))

Yes, that would be the workaround for this. However, I like the way with variables for hue etc. to know what they are used for (what I need to change to achieve the desired light effect).

The language is what it is at this point.