While Loops in Script/Rules (Hue continuous color shifting)

Hi All,

First post, so bare with me. I’m using the Aeotec USB Stick Gen5 and a few Hue bulbs. I have some simple rules that can change the color and state of the lights on command. I’m trying to initiate a “Party Mode”, where the lights continuously shift colors with a slow transition.

I can write a rule/script combination that can do this for a specific amount of time, but how would I stop the script from executing once it starts?

Also, if there is an easy way to stop the script from executing, is it possible to implement a While Loop in a script so that it continues without a specific amount of time?

Thanks for your help!

I think I’ve found my own solution. Here’s what I came up with so others can benefit…

I have 3 Hue lights (Left of Couch, Right of Couch, and TV.

Items File Excerpt

/* Items for Hue Lights /*
Color	Hue_Couch_Left_Color	"Left of Couch Color"	<hue>	{hue="1"}
Color	Hue_Couch_Right_Color	"Right of Couch Color"	<hue>	{hue="2"}
Color	Hue_Strip_TV_Color	"TV Light Color"	<hue>	{hue="3"}

/*Party Mode empty Items */
Number	LvgRm_Party_Selector	"Party Mode Type"
Switch	LvgRm_Party_SW			"Party Mode ON/OFF"

**Sitemap Entry**

Frame	label="Living Room Party" {
	Selection	item=LvgRm_Party_Selector	label="Party Mode"	mappings=["1"="All Slow Transition","2"="Color Festival"]
	Switch	item=LvgRm_Party_SW	label="Start/Stop"
}

Rule file

rule	"Party Mode Starter"
when
		Item LvgRm_Party_SW received command ON
	then
		callScript("party_mode.script")
	end

Script File (party_mode.script)

val java.util.Random rand = new java.util.Random
var	Integer num

if (LvgRm_Party_Selector.state == 1) {
	postUpdate(Hue_LivingRm_All, ON)
	while (LvgRm_Party_SW.state != OFF && Hue_LivingRm_All.state != OFF) {
		color = rand.nextInt(360)
		brightness = rand.nextInt(100)
		sendCommand(Hue_Couch_Left_Color,color.toString + ",100," + brightness.toString)
		sendCommand(Hue_Couch_Right_Color,color.toString + ",100,"+ brightness.toString)
		sendCommand(Hue_Strip_TV_Color,color.toString + ",100,"+ brightness.toString)
		Thread::sleep(3000) 
	}
	sendCommand(Hue_Couch_Left_SW, OFF)
	sendCommand(Hue_Couch_Right_SW, OFF)
	sendCommand(Hue_Strip_TV_SW, OFF)
	postUpdate(Hue_LivingRm_All, OFF)
}

Explanation
The rule calls the script “party_mode.script” of the switch is turned on.
(Sidenote: Seems to me that scripts are able to read item states without recompiling, making them much faster when real-time updates are needed based on state.)

The script runs a while loop that checks the state of the switch as the conditional (I’ve got 2 switches in this one). A Random Number is generated at each iteration that is used for the color hue of the bulb. Then sendCommand(item, string of hue) to each of the lights. Thread::sleep(5000) changes it every 5 seconds.

Once the switch is turned off, it’ll turn them all off.

Seems to work for now. Updating the random number between the sendCommands adds the effect of each light changing to something different (another cool effect).

If anyone sees something I missed or is incorrect, please let me know.

Thanks.

Looks good! Some minor comments:

  • this could also be simply the body of the rule, the only real benefit to having it be a script is if you would call it from multiple different rules in multiple .rules files
  • it is more standard to compare the state of a Switch Item to ON, or OFF rather than the toString value
  • indeed, the current states of Items are available both in scripts and rules
  • when posting code to the forum, it is helpful to use the code formatting; there are lots of ways to do this but the easiest is to wrap your code in three back ticks or to indent each line by four spaces

When testing, it seemed like the way the rule was written, it was causing delay when I included the state validation within the rule. When utilized the script, the delay went away. I read on another post that the rules have to “recompile” when they are changed. Maybe the rule was recompiling everytime I updated the state?

Good catch. I’ll update. :slight_smile:

Sounds good. I wrapped it in “code” markup, but that didn’t come out the way expected. I’ll start using the backticks.

Cheers

I don’t think that is how it works. When you change your rules files (or your script files for that matter) OH will reload and “compile” them to make them available for execution, but they are not recompiled at every execution.

Not know what is in your logs or what sort of delay you may be seeing I can’t begin to guess as to why you saw a delay.

Hey Guys,

Have had a couple of cracks at this because I thought it would be cool and because I thought it would help me learn about scripts but no success :frowning:

I have copied Ed’s code but I get the following error:

Error during the execution of rule ‘hue test’: An error occured during the script execution: org.eclipse.xtext.util.PolymorphicDispatcher$NoSuchMethodException: Couldn’t find method ''assignValue’’ for objects [JvmVoid: (eProxyURI: party_mode.script#xtextLink::0.0.2.1.0.1.1.0.0::0::/1), color , 201, org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext@220f0aa1, org.eclipse.xtext.util.CancelIndicator$1@7523801a]

I’m guessing something obvious but can’t find it.

thanks

This is working great for me in 2022 on OH3 thank you for your work!

It would be great to know what you did for your LvgRm_Party_Selector.state = 2 if you still have your scripts and wouldn’t mind sharing?

Thanks! :slight_smile: