Need help to correct rule

Hi guys, maybe you cant help me to corect my rule script?

I want to add a timer in following rule:

following rule works:

rule "ASTRO_ Sonnenaufgang_Rolläden_EG"
when
    	Channel "astro:sun:home:rise#event" triggered START
then
	if 	(Rollo_Autom_EG.state==ON && Rolladen_Sonnenschutz_EG.state==ON)   	[|Alle_Rolladen_EG.members.forEach(s|s.sendCommand(50))]}
	if 	(Rollo_Autom_EG.state==ON && Rolladen_Sonnenschutz_EG.state==OFF)   	[|Alle_Rolladen_EG.members.forEach(s|s.sendCommand(5)) ]}  
end

folowing rule will NOT work:

rule "ASTRO_ Sonnenaufgang_Rolläden_EG"
when
    	Channel "astro:sun:home:rise#event" triggered START
then
	if 	(Rollo_Autom_EG.state==ON && Rolladen_Sonnenschutz_EG.state==ON)   	{createTimer(now.plusMinutes(30)) [|Alle_Rolladen_EG.members.forEach(s|s.sendCommand(50))]}
	if 	(Rollo_Autom_EG.state==ON && Rolladen_Sonnenschutz_EG.state==OFF)   	{createTimer(now.plusMinutes(55)) [|Alle_Rolladen_EG.members.forEach(s|s.sendCommand(5)) ]}
end

Sorry i think this is not a big problem, but unfortunately i can’t find the syntax error myself…

Could someone please give me a hint?
Thanks a lot!

Let’s start with the first block
Are you sure this is working? The is a closing } without an opening { which looks weird to me. Also there is no reason to use the closure (anonymous function) with [| ] here. Rather only use { }

rule "ASTRO_ Sonnenaufgang_Rolläden_EG"
when
    	Channel "astro:sun:home:rise#event" triggered START
then
	if 	(Rollo_Autom_EG.state==ON && Rolladen_Sonnenschutz_EG.state==ON)   
         [|Alle_Rolladen_EG.members.forEach( s | s.sendCommand(50) )]
        }
	if 	(Rollo_Autom_EG.state==ON && Rolladen_Sonnenschutz_EG.state==OFF)  	 
         [|Alle_Rolladen_EG.members.forEach(s|s.sendCommand(5)) ]}  
end

foreach works like that

Alle_Rolladen_EG.members.members.forEach[ item | 	
			item | item.sendCommand(50)
		]

Regarding the second block, there is also a syntax error when using the create timer function.

rule "ASTRO_ Sonnenaufgang_Rolläden_EG"
when
    	Channel "astro:sun:home:rise#event" triggered START
then
	if 	(Rollo_Autom_EG.state==ON && Rolladen_Sonnenschutz_EG.state==ON) {
          createTimer( now.plusMinutes(30) )  // <-- wrong closing bracket
            [ |Alle_Rolladen_EG.members.forEach( s| s.sendCommand(50)) ] 
        }
	// 2nd part omitted
end

The syntax for createTimer is as follows (note, that the closure is the second parameter of createTimer)

if timer === null) {
        timer = createTimer(now.plusMinutes(5), [ |
            //Do the timer stuff
            timer = null // cancel the timer
        ])
    }

(note: I have not test anything of the above, so take it with a grain of salt)

I may be biased but maybe blockly rules allow you to write your code in quicker and less error prone way with timers which are easy to get wrong with the above syntax.

Doesn’t work how? Errors in the logs?

Note, you don’t need a forEach to send commands to all members. Just send the command to the Group and OH will forward the command to all members of the Group.

Beyond that, I see nothing wrong with the way this rule is written.

Add logging to verify:

  1. that the rule is running
  2. the state of Rollo_Autom_EG when the rule runs
  3. the state of Rolladen_Sonnenshutz_EG when the rule runs
  4. add a log statement to the inside of the timers so you can see when they run.
  5. Make the timers way shorter for testing and manually trigger the rule from MainUI to test.

I must be tired. I didn’t see any of this. Posting the above as general debugging advice.

Because the OP’s timers are throw away timers, there’s no timer variable that needs to be checked and reset so that part’s OK.

Instead of using timers, I’d consider if using the Astro binding with an offset isn’t a better option.

Verry Thanks for your support!
I found the problem by testing the rule with the mentionde 5 steps :slight_smile:

i correct the rule from
old one:

if 	(Rollo_Autom_EG.state==ON && Rolladen_Sonnenschutz_EG.state==ON)   	{createTimer(now.plusMinutes(30)) [|Alle_Rolladen_EG.members.forEach(s|s.sendCommand(50))]}

to new one:

if 	(Rollo_Autom_EG.state==ON && Rolladen_Sonnenschutz_EG.state==ON)   	{createTimer(now.plusMinutes(30)) [ Alle_Rolladen_EG.members.forEach(s|s.sendCommand(50))]}

the solution was just to remove the symbol “|”

Thanks for your help

1 Like