call a event from a rule

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
rira2005
Normal user
Posts: 30
Joined: 25 Jun 2017, 21:09

call a event from a rule

#1 Post by rira2005 » 19 May 2021, 23:26

hi al allready add 3 events, they are working fine

on forward do
if [R2#state]=0
gpio,13,1
gpio,12,1
delay,1000
gpio,13,0
GPIO,14,1
else
gpio,13,0
GPIO,14,1
endif
endon

on stop do
gpio,12,1
gpio,13,1
GPIO,14,0
endon

on reverse do
if [R1#state]=0
gpio,13,1
gpio,12,1
delay,1000
gpio,12,0
GPIO,14,1
else
gpio,12,0
GPIO,14,1
endif
endon

but i want to call any of this event when i push a button
on Button#State do
"call event reverse
endon

is this possible?

Many Thanks
Rira

User avatar
Ath
Normal user
Posts: 3415
Joined: 10 Jun 2018, 12:06
Location: NL

Re: call a event from a rule

#2 Post by Ath » 20 May 2021, 09:35

rira2005 wrote: 19 May 2021, 23:26 but i want to call any of this event when i push a button
on Button#State do
"call event reverse
endon
You're already very close:

Code: Select all

on Button#State do
 event reverse // A comma can also be used instead of the space separator
endon
and if you need to add %eventvalue% arguments, you should do that like this:

Code: Select all

  event,"reverse=1,2,3,4" // just example arguments to have something in %eventvalue1% to %eventvalue4%
NB: To queue the event after all currently 'waiting to be executed' events, the 'asyncevent' command should be used instead of 'event'.

Edit: Added the required quotes.
Last edited by Ath on 20 May 2021, 10:24, edited 1 time in total.
/Ton (PayPal.me)

User avatar
Ath
Normal user
Posts: 3415
Joined: 10 Jun 2018, 12:06
Location: NL

Re: call a event from a rule

#3 Post by Ath » 20 May 2021, 09:44

rira2005 wrote: 19 May 2021, 23:26 on reverse do
if [R1#state]=0
gpio,13,1
gpio,12,1
delay,1000
gpio,12,0
GPIO,14,1
else
gpio,12,0
GPIO,14,1
endif
endon
You have a delay of 1000 milliseconds, but the documentation states to avoid using the delay command, as delay is blocking execution for the entire unit. 1 second isn't really terrible, but it would be better to use a timer, like this example:

Code: Select all

on reverse do
  if [R1#state]=0
    gpio,13,1
    gpio,12,1
    TimerSet_ms,1,1000
  else
    gpio,12,0
    GPIO,14,1
  endif
endon

on rules#timer=1 do
  gpio,12,0
  GPIO,14,1
endon
For other events, also in need of a similar timer, currently there are 8 timers available (shared with the LoopTimerSet commands).
/Ton (PayPal.me)

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: call a event from a rule

#4 Post by TD-er » 20 May 2021, 09:57

Ath wrote: 20 May 2021, 09:35 [...]
and if you need to add %eventvalue% arguments, you should do that like this:

Code: Select all

  event,reverse=1,2,3,4 // just example arguments to have something in %eventvalue1% to %eventvalue4%
[...]
This particular example given by Ton may need some extra attention.

The argument of event is "reverse=1,2,3,4", which contains a comma.
So it should be wrapped in quotes:

Code: Select all

  event,"reverse=1,2,3,4" // just example arguments to have something in %eventvalue1% to %eventvalue4%
For event, it will still work as event only expects a single parameter, but it is best to be aware of the effects.

And the other remark made by Ton should be considered for multiple reasons.
It is better to use asyncevent, compared to event.
Sometimes you need to have an event handled before you can continue, so then you can't use asyncevent, but try to use asyncevent where possible.

'event' is executed immediately, but does require the rules engine to start a new parsing of the rules.
This may need extra resources and may cause a 'stack overflow' (crash) if you call another event from that event, and another one, etc.
Not only does it consume a lot more resources, but also it does take a lot of time in which other jobs of the ESP cannot run (e.g. handling web page, acting on a sensor, taking a reading, etc.)

asyncevent does return immediately, as it only adds the event (+ event values) to a queue of events.
Queued events are handled in the order you create them, but they may be executed out of order compared to "event" calls.
Thus if those are depending on each other, they all should be either "event" or "asyncevent" calls.

Bben
New user
Posts: 8
Joined: 17 May 2021, 10:15

Re: call a event from a rule

#5 Post by Bben » 20 May 2021, 11:40

Hi,

I would add a subsidiary question/note to this one,

I use event call in rules to mimic method/function call.

I noted that if I launch an event, which launch an another one which launch a third one (not sure of the exact depth), the wemos crash and reboot.

If I prevent a direct event call by launching it with a millisecond timer, it would'nt crash anymore.

Is there any limitation here or it's due to the hardware?

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: call a event from a rule

#6 Post by TD-er » 20 May 2021, 12:08

That's (almost) exactly the same effect as calling an asyncevent.
A timer event is a scheduled event. So it is not added to the event queue, but it is also not executed immediately as what the "event" command would do.

See it as a normal stack in programming.

Code: Select all

void functionA() {
  functionB();
}

void functionB() {
  functionC();
}

void functionC() {
  functionA();
}
This will create infinite recursion => stack overflow => crash
What our rules parser does each time it calls "event" is it pauses execution of the current rules, call a new rules parser (including all needed variables to keep track of the state of the parser) and start parsing from the beginning of the first rules file.
This does add to the very limited stack we have and on top of that does consume quite a bit of heap memory too.
Not sure what happens first, stack overflow or running out of heap memory.

So this should be avoided by either calling asyncevent, or schedule a timer (which is essentially the same, only executed at some time, instead of from a queue)

Bben
New user
Posts: 8
Joined: 17 May 2021, 10:15

Re: call a event from a rule

#7 Post by Bben » 20 May 2021, 21:59

Thanks for the explanation TD-er,

I've take car to avoid any loop in the call,
In my example it calls event from 2/3 different rule file, half of max size each.
I will test the AsyncEvent command i've passed through!

rira2005
Normal user
Posts: 30
Joined: 25 Jun 2017, 21:09

Re: call a event from a rule

#8 Post by rira2005 » 04 Jun 2021, 11:13

Thank you very Much. i allready handled it to call an event! Many Thanks to all!

Post Reply

Who is online

Users browsing this forum: No registered users and 29 guests