Skip to content

Script expressions

Jan Gabrielsson edited this page Sep 5, 2018 · 41 revisions

Script expressions can be used as actions in Event.event(<event>,<action>), but most useful are script expressions to setup standalone rules. To setup a script rule, the Rule.eval("script expression") function is used.


Rule.eval

Rule.eval("#<event> => <expression>")
Rule.eval("daily(<time>)&<expression> => <expression>")
Rule.eval("<trigger expression> => <expression>")
Rule.eval("<expression>")

´Rule.eval´ evaluates the script expression and return the result. An expression containing an '=>' operator defines a rule that are saved and will be invoked according to events happening.
There are 3 types of rules;

  • Daily/scheduling rules. Any rule with a left hand side that contains a daily/@ expression will be called at that time-event. The rule can contain additional expressions but the rule will only be called at the time specified. Additional expression can be used to add extra conditions needed to be true for the rules right hand side to execute.
Rule.eval("@sunset-00:15 => kitchen.lamp:on"
Rule.eval([[@sunset-00:15 & $Presence~='away' => 
                kitchen.lamp:on; log('Turning on lamp')]])
Rule.eval([[@sunset-00:15 & wday('mon-fri') & $Presence~='away' => 
                kitchen.lamp:on; phone.jan:msg=log('Turning on lamp, Presence=%s',$Presence)]])
  • Event trigger rules. These will execute the <expression> if an incoming event is matched. Ex.
Rule.eval("#property{deviceID=66} => log('lamp changed state')")
Rule.eval("#property{deviceID=kitchen.lamp, value='$>0'} => log('kitchen lamp value=%s',value)")
Rule.eval("#loop{value='$i<10'} => log('value=%s',i); post(#loop{value=i+1},+/00:01)")
Rule.eval("post(#loop{value=1})")  
  • DeviceID/Globals expression triggering rules. Any other rule with a left hand side containing expression(s) dealing with deviceIDs or fibaro globals will be called when those IDs and/or globals change state.
Rule.eval("kitchen.lamp:isOn => log('kitchen lamp value=%s',kitchen.lamp:value)")

Expression without '=>' are just evaluated and the result is returned.


Rule.load

This is an convenience function to load many rules defined in one string. Rules spaning over multiple lines need additional lines to be intended.

Rule.load([[
   <expression1>
    <cont. of expression1>
    <cont. of expression1>
   <expression2>
    <cont. of expression2>
   ...
   ]])

Allows for loading and running multiple rules/expressions in one swoop... Ex.

Rule.load([[
      a=6;b=8
      log("%d+%d=%d",a,b,a+b)
      55:isOn => 77:off;
        log("Turning of lamp!")
   ]])

Script functions

Grammar

<symbol> ::= (a-zA-Z) (a-zA-Z_0-9)
<global> ::= $<symbol> 
<var> ::= <symbol>
<event> ::= #<symbol>{<symbol>=<expr>,...,<symbol>=<expr>}
<constant> ::= 'now' | 'midnight' | 'sunrise' | 'sunset' | 'wnum' | 'true' | 'false' | 'nil' | '{}' 
<time> ::= HH:MM | HH:MM:SS | YYYY/mm/DD/HH:MM | YYYY/mm/DD/HH:MM:SS
<timeExpr> ::= <time> | +/<time> | n/<time> | t/<time> 
<oper> ::= + | - | * | / | % | "|" | & | > | < | >= | <= | == | = | =~ | = | .. | .| : | ! | @
<expr> ::= <table> | <call> | <event> | <num> | <string> | <constant> | <var> | <global> | <timeExpr> | <addr>
<expr> ::= <expr> <oper> <expr> | - <expr> | ( <expr> )
<expr> ::= fn(<var>,...,<var>) <statements> end
<expr> ::= <expr> ? <expr> : <expr> -- not implemented yet...
<call> ::= <fun>(<expr>, ..., <expr>) | <var>(<expr>, ..., <expr>) | (<expr>)(<expr>, ..., <expr>)
<statements> ::= statement [ ; <statements> ]
<statement> ::= <expr>
<statement> ::= || <expr> >> <statements> {|| <expr> >> <statements>} [;;]
<rule> ::= @<time> [& <expr>] => <statements> | @{<time>, ..., <time>} [& <expr>} => <statements>
<rule> ::= @@<time> [& <expr>] => <statements> 
<rule> ::= <expr> => <statements> 
<rule> ::= <event> => <statements> 
  • <var>. User defined variables. If a variable doesn't exists, it is created when first assigned. Ex. a=42; print(a)
  • $<global>. References to global 'Fibaro' variables. Ex. $TimeOfDay='Night' = fibaro:setGlobal('TimeOfDay','Night')
  • #<event>[{<table>}]. Event structure. Ex. #property{deviceID=55} = {type='property', deviceID=55}. #test = {type='test'}
  • DD:DD[:DD]. Time constant. Ex. 00:10 = 60*10 seconds, 10:05:30 = 3600*10+5*60+30 seconds.
  • YEAR/MONTH/DAY/DD:DD[:DD]. Long date constant. Ex. 2018/12/25/08:00. Converted to seconds since 1 Jan. 1970 (os.time())
  • +/DD:DD[:DD]. Time constant + current time. Ex. +/00:10 = os.time()+10*60.
  • t/DD:DD[:DD]. Time constant + midnight.
  • n/DD:DD[:DD].
  • midnight. Constant for os.time() for last midnight
  • sunset,sunrise. Constant for seconds to sunset orsunrise from midnight
  • now. Constant for seconds since midnight to now. E.g. os.time()-midnight
  • wnum. Constant for week number. E.g. tonumber(os.date("%V"))
  • env. Constant containing the current environment. Ex. env.event.type=='property'
  • !. Operator for logical negation. Ex. !true
  • &. Operator for logical AND. Ex. `true & true´
  • |. Operator for logical OR. Ex. `true | false´
  • +,-,*,/,%. Mathematical operators. Ex. 55+66-7*3/2
  • +=,-=,*=. Increment variable. Ex. a+=7*3/2. Does not currently work with globals.
  • >,<,>=,<=,~=,==. Logical operators for comparision. Ex. 56 >= 44
  • progn.
  • frm. Format, like Lua's string.format. Ex. frm('%s+%s=%s',5,4,5+4)
  • log.Like frm but logs the result to the console. Ex. log('%s+%s=%s',5,4,5+4)
  • tjson. Converts arument to a json string. Ex. tjson({a=b})=='[a:b]'
  • osdate. Return os.date(). Ex. osdate('*t').wday=='Wed'
  • ostime. Return os.time(). Ex. ostime()
  • daily. Function for specifying daily event in left hand side of rules. Takes a time or array of times.
  • @. Unary operator version of daily. Ex. @10:00 => log("Hello!")
  • schedule. Function for for repeating a rule at intervals. Ex. schedule(00:10) => log('Hello!')runs the rule every 10min.
  • @@. Unary operator version of schedule. Ex. @@00:10 => log("Hello!")
  • :last. Return seconds since device last changed.
  • :on. Turn on light(s). Ex. 55:on, {55,66,77}:on
  • :isOn. Return true if (any) values of IDs are >0. Ex. 55:isOn, {55,66,77}:isOn
  • :isAllOn. Return true if (all) values of IDs are >0.
  • :off. Turn of light(s). Ex. 55:off, {55,66,77}:off
  • :isOff. Return true if (all) values of IDs are 0. Ex. 55:isOff, {55,66,77}:isOff
  • :isAnyOff. Return true if (any) values of IDs are 0.
  • :toggle. Toggle a 'light' ID. Ex. 55:toggle, {55,66,77}:toggle
  • :power. Synonym for :value.
  • :lux. Synonym for :value.
  • :value.
  • :msg=<string>. Push message. Ex. 55:msg='Hello', {55,66,77}:msg='Hello'
  • :btn=<num>.
  • :scene. Returns sceneActivation value for device
  • :start. Start scene. Ex. 66:start = fibaro:startScene(66)
  • :stop. Stop scene. Ex. 66:stop = fibaro:killScene(66)
  • :safe. Same as :isOff
  • :breached. Same as :isON
  • post. Post an event. Ex. post(#foo{val=66+2},n/10:00)posts event {type='foo',val=68} at the next 10 o'clock. The time argument is optional and defaults to now.
  • label.
  • manual.
  • betw. Checks if time is in intervall.Ex. betw(10:00,11:00). A shorthand syntax is 10:00..11:00 as the operator ..expands to betw.
  • once.
  • for.
  • repeat.
  • <fun>.