Snips.AI Rule Functions to change Color of Light

Hello Community,

I have used OpenHab2 for some time now and have read alot of the tutorials on this page to get started. So far I have figured everything out by myself although some rules might not be as elegant as they could be everything works out just fine :grinning:

I now have a problem I can´t seem to figure out by myself though, mainly because I don´t now how to program anything else than basic stuff. I have OpenHab2 running inside a VM on my HomeServer, a couple of days ago I installed Snips.ai on a Raspberry Pi. I have set up everything and it works great. The problem is that I can`t use anything else than simple ON/OFF Commands. I would like to be able to change the Color of e.g. the Living Room Bulbs but I don´t know how to program that.

Right now the part of my my snips.rule which should change color according to whats posted in Snips_Intent looks like this:

rule "Snips Intent"
when
  Item Snips_Intent received update
then
  logInfo("Snips Intent: ", Snips_Intent.state.toString)
end 

rule "Snips"
when 
    Item Snips_Intent received update
then 
 
logInfo("Snips Intent: ", Snips_Intent.state.toString)
 
var String intentName = transform("JSONPATH", "$.intent.intentName", Snips_Intent.state.toString)
var String pureIntent = intentName.split(":").get(1);
var String device_val = transform("JSONPATH", "$.slots[0].value.value", Snips_Intent.state.toString)
var String color_val = transform("JSONPATH", "$.slots[1].value.value", Snips_Intent.state.toString)

logInfo("Snips Gerät: ", device_val)
logInfo("Snips Farbe: ", color_val)
 
pureIntent = pureIntent.toLowerCase
 
logInfo("Snips device value: ", pureIntent)

function getColorValue(c) {
  switch (c) {
    case 'white':  return '0,0,100';
    case 'rose':   return '300,100,10';
    case 'yellow':  return '500,100,100';
    case 'orange': return '25,100,100';
    case 'green':   return '100,100,50';
    case 'violet': return '280,100,100';
    case 'blue':   return '200,100,100';
    case 'red':  return '0,100,100';
    default:       return '0,0,100';
  }
}

if (pureIntent == 'farbewechseln') {
  oh2COLOR = "getColorValue(color)"
}
 
if (device_val == 'Wohnzimmer') {
  sendCommand(WZFarbe,oh2COLOR)
}

Once I upload the rule it says:

2019-02-12 20:04:13.331 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'snips.rules' has errors, therefore ignoring it: [40,36]: missing '}' at ';'
[41,5]: mismatched input 'case' expecting '}'
[41,16]: mismatched input ':' expecting 'end'

So there seems to be a mistake in the “function getColorValue” part. Does anyone now a solution to this problem? Thanks in advance!

Doesn’t work like that in openHAB rules. You can define functions, but with a different form and generally referred to as ‘lambdas’.

Okay, I just copied the getColorValue function from another OpenHab Thread, good to know it can`t work ;). Lambda seems pretty complex, I will have to try it out though it seems…

It’s not that much code to just put inline, never mind a function.

Could you give me an example for that code?

// inline color conversion
var rgbcode = "0,0,100"  // default
 switch c {
   case 'white': { rgbcode = "0,0,100" }
   case 'rose': { rgbcode = "300,100,10" }
   case 'yellow': { rgbcode = "500,100,100" }
   case 'orange': { rgbcode = "25,100,100" }
   case 'green': { rgbcode = "100,100,50" }
   case 'violet': { rgbcode = "280,100,100" }
   case 'blue': { rgbcode = "200,100,100" }
   case 'red': { rgbcode = "0,100,100" }
}

if (pureIntent == 'farbewechseln') {
  oh2COLOR = rgbcode
}

Thank you for the example! Uploading works just fine, the error from before is gone, unfortunately now the Log File comes up with the following line:

Rule 'Snips': The name 'c' cannot be resolved to an item or type; line 41, column 9, length 1

This is referring to the “switch c {” line. Do you know what to change?

Oh I missed that bit. In your original code you had -

so I suppose color is the variable you have defined elsewhere that you need to switch-case on

Ok I think I get that!

I re-wrote your rule so that it should change the item “ColorLamp” once the variable “color_val” gets updated through the Transformation of the JSONPATH. It now looks like this, but its still not working:

var rgbcode = "0,0,100"  // default
 switch ColorLamp {
   case 'color_val == white': { rgbcode = "0,0,100" }
   case 'color_val == rose': { rgbcode = "300,100,10" }
   case 'color_val == yellow': { rgbcode = "500,100,100" }
   case 'color_val == orange': { rgbcode = "25,100,100" }
   case 'color_val == green': { rgbcode = "100,100,50" }
   case 'color_val == violet': { rgbcode = "280,100,100" }
   case 'color_val == blue': { rgbcode = "200,100,100" }
   case 'color_val == red': { rgbcode = "0,100,100" }
}

Log:
Rule 'Snips': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null

I will try to find a workaround tomorrow though as its getting late. :wink: I have a feeling I`m on the right track though, many thanks to you!!

If ColorLamp is as you say an Item, you’re probably interested in its state ColorLamp.state for use in a switch-case.

But it looks like you’ve decided to select case on some color_val variable. You’d put that in the switch statement and do away with all those comparisons, switch-case does that all by itself.
Does exactly like your last post -

switch color_val {
   case "white": { rgbcode = "0,0,100" }

The error you report suggests you’ve tried to send a command without a valid value. I’d guess oh2COLOR never got set to anything, there doesn’t seem to be any way it gets set if (pureIntent == 'farbewechseln') doesn’t get satisfied.

Maybe its easier for me to understand If I break the whole thing down for you again, because I just can`t seem to get it to work… Once this is done your next beer is on me btw :wink:

I activate Snips saying e.g. “Hey Snips, please change the color in the living room to red”

The Sentence gets broken down into different pieces updating the variables Set in

var String intentName = transform("JSONPATH", "$.intent.intentName", Snips_Intent.state.toString)
var String pureIntent = intentName.split(":").get(1);
var String device_val = transform("JSONPATH", "$.slots[0].value.value", Snips_Intent.state.toString)
var String color_val = transform("JSONPATH", "$.slots[1].value.value", Snips_Intent.state.toString)

According to the sentence --> “change color in living room to red” the variables are now:

intentName/pureIntent = ‘farbewechseln’
device_val = ‘living room’
color_val = ‘red’.

Now for the problem: The color red (color_val) cant be sent to the Lamps directly, since it is not a RGB Code! It has to be transformed to an RGB Code first for which your suggested rule should work! What I still can`t seem to understand (Lack of programming knowlegdge I guess) is how this

// inline color conversion
var rgbcode = "0,0,100"  // default
 switch ExampleItem {
   case 'white': { rgbcode = "0,0,100" }
   case 'rose': { rgbcode = "300,100,10" }
   case 'yellow': { rgbcode = "500,100,100" }
   case 'orange': { rgbcode = "25,100,100" }
   case 'green': { rgbcode = "100,100,50" }
   case 'violet': { rgbcode = "280,100,100" }
   case 'blue': { rgbcode = "200,100,100" }
   case 'red': { rgbcode = "0,100,100" }
}

if (pureIntent == 'farbewechseln') {
  oh2COLOR = rgbcode
}

gets updated with the color ‘red’ so it can be transformed to the matching RGB Code and can then be sent to the Lamps accordingly. The switch function updateds an item of my choosing, that i understand but how does it get the input “red”? I hope I have made myself clear, its kind of hard to really explain my problem I guess.

I think you misunderstand the switch-case function. It’s just a glamourized if - elseif - elseif - else.

Switch means “use this variable to choose among these various cases”

switch somevariable {
   case "fred" :  {  // somevariable contains 'fred' }
   case "nelly" : { // somevariable contains 'nelly'
                           // this stuff can be multilines of code }
   default : { // somevariable is something the programmer didn't expect }
}
// somevariable is not changed in any way by this process
// unless you choose to change it in the case parts