Jump to content

Recommended Posts

Lets see if i got this right

  Rule.eval("#location{user='Jonny', place='Home'} & $UHASDarkness=='Mörkt' => VD.taklampaSonoff:btn=1")
  Rule.eval("#location{user='Mona', place='Home'} & $UHASDarkness=='Mörkt' => VD.taklampaSonoff:btn=1")
  Rule.eval("for(00:15,label(VD.taklampaSonoff,'Label1')=='ON') => VD.taklampaSonoff:btn=2")  
 

Rule #1 will pressButton on my VD when i arrive at home and it is dark

Rule #2 same as #1 except user

Rule #3 will pressButton 2 after 15min if Label1 is "ON"

 

All true @jgab ?

Link to post
Share on other sites
  • Replies 2.6k
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Note. The first ~2000 posts of this thread is mainly about EventRunner3 that is for the HC2. EventRunner3 is not developed further, but bugs are fixed as they are reported. For HC3, the version i

I've been playing with the HC3 a bit  (I don't own a HC3 but a friend has allowed me to remotely login to do testing - I'm very grateful for that). ...and I have made some progress with EventRunn

Working with event runner rules it can be useful to understand a bit how they work behind the "hood". Rules are always on the form   <test> => <statments> Ex 88:breached

Posted Images

40 minutes ago, jompa68 said:

Lets see if i got this right

  Rule.eval("#location{user='Jonny', place='Home'} & $UHASDarkness=='Mörkt' => VD.taklampaSonoff:btn=1")
  Rule.eval("#location{user='Mona', place='Home'} & $UHASDarkness=='Mörkt' => VD.taklampaSonoff:btn=1")
  Rule.eval("for(00:15,label(VD.taklampaSonoff,'Label1')=='ON') => VD.taklampaSonoff:btn=2")  
 

Rule #1 will pressButton on my VD when i arrive at home and it is dark

Rule #2 same as #1 except user

Rule #3 will pressButton 2 after 15min if Label1 is "ON"

 

All true @jgab ?

Yes, but "event triggers" can't have any other tests on the left hand side (it may change in the future), so you move the darkness test to the right.

Rule.eval("#location{user='Jonny', place='Home'} => $UHASDarkness=='Mörkt' & VD.taklampaSonoff:btn=1")
Rule.eval("#location{user='Mona', place='Home'} => $UHASDarkness=='Mörkt' & VD.taklampaSonoff:btn=1")
Rule.eval("for(00:15,label(VD.taklampaSonoff,'Label1')=='ON') => VD.taklampaSonoff:btn=2")  

Ok, but if you are already home and Mona comes home and it's dark it still presses the button? That's why I had the logic that when the first person came home it sent #presence{state='home'} and one could trigger on that.

<exprA> & <exprB> is like an IF <exprA> then  <exprB>...

Third rule looks ok.

Link to post
Share on other sites

@jgab do you know how often phone location update to apple servers?
It did take almost 5 min before it did update when i did arrive to home, this mean the lights did not turn on like i want.
Have you notice the same behavior?

 

Update

I notice that i was not logged on to "find my iPhone" app, perhaps it was that?

Edited by jompa68
Link to post
Share on other sites
18 minutes ago, jompa68 said:

@jgab do you know how often phone location update to apple servers?
It did take almost 5 min before it did update when i did arrive to home, this mean the lights did not turn on like i want.
Have you notice the same behavior?

Well, it seems like they update every minute (when you run the FindFriends app on the phone it updates every minute).

Having said that, I have seen a lot of varying update intervals. 

The loop in the iOSLocator loops through the people/family members checking one person each minute, so if you are 4 person it check each person every 4 minutes, are you 2, it becomes every second minute. You can try to lower that interval (line 222 in iOSLocator), to check more often. However, too frequent checks to the server (10''s per minute for the same person) seems to make Apple block you for a while... I had that bug once :-) 

You can also experiment with the radius to the home so iOSLocator detects that you are close to home earlier. I used to have a radius of 800m to detect if people were home or not and start/stop the alarm, and it worked 9/10 times (I usually arrived by car). Now I just moved so I don't have an alarm yet.

Link to post
Share on other sites
16 hours ago, jgab said:

You can try to lower that interval (line 222 in iOSLocator), to check more often.

 

This line

post({type='poll',index=index+1},"+/00:01") -- check every minute

to

post({type='poll',index=index+1},"+/00:00:30") -- check every 30 sec

:?:

Link to post
Share on other sites
26 minutes ago, jompa68 said:

 

This line

post({type='poll',index=index+1},"+/00:01") -- check every minute

to

post({type='poll',index=index+1},"+/00:00:30") -- check every 30 sec

:?:

Yes.

Do you have a large enough radius defining “home”? 

Link to post
Share on other sites
7 minutes ago, jompa68 said:

Yes i think so. 

dist":0.8,

 

Yes, that should work.

Link to post
Share on other sites

@jgab

 

is ti possible to check variable that wasn't change for some period of time? (I know it will generate error but maybe you have some simple solution in your framework)

 

  rule("for(00:02, test==10) => log('Variable test had 2 minutes value 10')")
 

Link to post
Share on other sites
42 minutes ago, petrkl12 said:

@jgab

 

is ti possible to check variable that wasn't change for some period of time? (I know it will generate error but maybe you have some simple solution in your framework)

 

  rule("for(00:02, test==10) => log('Variable test had 2 minutes value 10')")
 

No, it only works for fibaro globals now i.e. $x. I'm afraid that triggering on local variables could cause a lot of strange unintended behaviours and even performance issues... I have to trigger all rules where the local is used, ex.

Rule.eval("a > 10 => log('>10')")
Rule.eval("a <= 10 => log('<=10')")

Rule.eval("wait(01:0); a=10")

That last expression would trigger the first two rules (and the second would log)...

To let this loose on variables in general feels a bit dangerous...

Maybe some special kind of trigger variable, so one doesn't need to use a fibaro global. 

Let me think about it.

Now one could do.

Rule.eval("#setTest{val='$x'} => ref=cancel(ref); test=x; ref = post(#timeOut{t=2},+/00:02)")
Rule.eval("#timeOut{t='$t'} => log('test have had same value (%s) for %s minutes'),test,t)")

Rule.eval("post(#setTest{val=10},+/00:05)")

 

Do you have a specific use case? The solution can differ a lot depending what it is you want to achieve.

Edited by jgab
Link to post
Share on other sites

OK, I know it will be complicated

but what about to use for example special type of value: $$ and trigger only this variables

 

Rule.eval("$$a=5")
Rule.eval("wait(01:00); $$a=10")

Rule.eval("for(00:02, $$a==10) => log('Variable $$a had 2 minutes value 10')")
Rule.eval("$$a==10 => log('Variable $$a has value 10')")

 

 

Edited by petrkl12
Link to post
Share on other sites
1 hour ago, petrkl12 said:

OK, I know it will be complicated

but what about to use for example special type of value: $$ and trigger only this variables

 

Rule.eval("$$a=5")
Rule.eval("wait(01:00); $$a=10")

Rule.eval("for(00:02, $$a==10) => log('Variable $$a had 2 minutes value 10')")
Rule.eval("$$a==10 => log('Variable $$a has value 10')")

 

 

Ok, pushed a new version that triggers on variables starting with an underscore.

Rule.eval("for(00:05,_foo==10) => log('value of _foo has been 10 for 5min')")
Rule.eval("_foo >= 10 => log('Value of _foo is %s',_foo)")

Rule.eval("wait(00:10); _foo=10")

Whenever the value of a variable starting with underscore is changed an event {type='variable, name=<name>, value=<value>} is posted.

So, it works ok for now but I will optimise it a bit how these events are dispatched in the future.

  • Like 1
Link to post
Share on other sites

With great power comes great responsibility.

Rule("_test+=1 = true")

Will create an infinite loop. (that's why there shouldn't be any side effects on the left hand side of a rule)

On the other hand

Rule.eval("_i < 10 => log('_i = %s',_i); _i+=1") -- loop while _i is less than 10
Rule.eval("_i=1") -- start loop at 1

is a rather elegant loop construct.

 

Edited by jgab
Link to post
Share on other sites

OK, Thanks for explanation of potential issue

BUT I think that it has really huge potential how to use it!

 

Link to post
Share on other sites
13 minutes ago, petrkl12 said:

OK, Thanks for explanation of potential issue

BUT I think that it has really huge potential how to use it!

 

Ok,

I just pushed a new version where there is a script compiler error if a trigger variable or a fibaro global is assigned in the rule header (left hand side).

e.g.

Rule.eval("_test+=1 => true")

07:48:40:Wed Nov 07: Error loading rules:Error evaluating '_test+=1 => true @line 36' EventRunner.lua:849: EventRunner.lua:1224: Can't assign variable in rule header

A subtlety is also that trigger variables will not trigger if their values changes (from whatever old value they held). That is more consistent on how fibaro's own global variables behave. 

e.g.

Rule.eval("_test==10 => _test=10")

will not create an infinite loop.

Edited by jgab
Link to post
Share on other sites

Made some changes in EventScript syntax. New version pushed.

CentralSceneEvent is triggered like this.

Rule("55:central => log('Key pressed %s',55:central.keyId)")
Rule("55:central.keyId=='2' => log('Key 2 pressed')")
Rule("{55,66}:central.keyId=='2' => log('Key 2 pressed on device %s',env.property.deviceID)")

What's happening behind the scene is that an event of type

{type='event', event={type=<eventType>, data={...}}}

is internally reposted as {type='property', deviceID=<ID>, propertyName=<eventType>, data=data}.

I have to know what <eventType> it is to be able to pick up the <ID> and insert it in the new event (seems to be no consistency in naming event data fields...).

So for the moment it can only deal with CentralSceneEvent and AccessControlEvent. If you know about other types of event I can easily add them.

Anyway, it results in that I can easier use the ':property' syntax like in the example. It also means that the event in 'env.event' has the structure {type='property', deviceID=<ID>, propertyName=<eventType>, data=data}

 

AccessControlEvent is similar.

Rule("55:access => log('Status is %s',55:access.status)")
Rule("55:access.status=='Unlock' => log('Unlock')")
Rule("{55,66}:access.status=='Unlock' => log('Device %s unlocked',env.property.deviceID)")

Both the ':central' and ':access' returns the 'data' field of the event.

SceneActivation is still accessed as 55:scene

Edited by jgab
Link to post
Share on other sites
1 minute ago, petrkl12 said:

@jgab

Thanks for adding that features.

 

How to use in :central for example long press of button?

Rule.eval("66:central.keyId=='1' & 66:central.keyAttribute=='HeldDown' => log('long press of key 2')")

--alt.
Rule.eval("key=66:central & key.keyId=='1' & key.keyAttribute=='HeldDown' => log('long press of key 2')")

--alt.
Rule.eval("key=66:central => key.keyId=='1' & key.keyAttribute=='HeldDown' & log('long press of key 2')")

--alt.
Rule.eval([[key=66:central.keyAttribute=='HeldDown' =>
     || 66:central.keyId=='1' >> log('long press of key 1')
     || 66:central.keyId=='2' >> log('long press of key 2')     
     || 66:central.keyId=='3' >> log('long press of key 3')
     || 66:central.keyId=='4' >> log('long press of key 4')     
     || 66:central.keyId=='5' >> log('long press of key 5')
     || 66:central.keyId=='6' >> log('long press of key 6')]])

-- or variations of thereof..

 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...