Events Programming
The EVENTS programming environment is based on a simple language that associates one or more actions to a field event or combination of conditions.
Programming EVENTS is as simple as editing the events.txt file, located in the main directory. Compared to Java, there is no compilation process. When you save the file, it is automatically reloaded and becomes immediately effective.
An event is an expression that refers to the persistent status or transient event of devices, to conditions applied to local variables, and to various internal events. An action is a control command sent to a device, or several other internal functions, like setting variables and program timers.
Example:
IO k.33 = 1 : k.34 = 1
when the light actuator with data point name k.33 is turned on, HSYCO automatically turns on the actuator with data point name k.34.
Example:
DAY : IO k.33 k.34 k.35 k.36 = 0
at sunrise, the actuators named k.33, k.34, k.35 and k.36 are turned off.
In this chapter we will describe the general format of events.txt, and all the built-in events and actions.
The events.txt file is usually modified with the text editor in HSYCO’s File Manager. When you save the file, it is automatically checked and, if errors are found, a warning icon appears in the top bar.
Touch that icon to show the list of errors. Errors are also written in the log file. Lines containing errors are ignored.
You can also enable the editor’s syntax highlighter for improved readability.
Contents
The EVENTS Language
EVENTS uses the simple format:
event : actions
Several events can be combined together to implement complex expressions which represent the combination of different conditions.
The logical operators AND, OR, NOT and the round brackets are available to define the operations precedence.
If the brackets are not used, the AND and OR operations are executed from left to right. The NOT operator has priority and is executed on the first expression after it, before AND or OR conditions.
Example:
IO k.33 OR IO K.34
this event occurs any time the actuators 33 or 34 change their status.
Example:
CAMERA "entrance" AND NOT IO K.34 = 0
is an event that occurs when the camera “entrance” starts recording, but only if the K.34 datapoint is not 0.
Example:
IO k.33 > 5 OR IO K.34 = 0 AND IO K.35 = 0
is equivalent to
(IO k.33 > 5 OR IO K.34 = 0) AND IO K.35 = 0
Example:
NOT IO k.33 = 1 AND IO k.34 = 1
is equivalent to
(NOT IO k.33 = 1) AND IO k.34 = 1
Comments
Comments are vital to describe the functions, even if the EVENTS language is very easy to understand.
A comment is identified by the # character.
All characters following # will be ignored until the end of line, unless the # character is enclosed between double quotes.
Example:
# actions executed at sunset NIGHT: IO k.33 k.34 k.35 k.36 = 1, # garden lights on IO k.43 k.44 = UP, # rise the awnings LOG = "# and this is not a comment"
Other General Rules
Keywords are case insensitive. Devices ids are also case insensitive. The EVENTS interpreter converts all ids to lower case, so it is recommended to use only lower case ids in hsyco.ini if you use EVENTS.
The built-in constant values (ON, OFF, UP, DOWN, STOP, FLIP, RECON, RECOFF, MERGE, UNMERGE, PLAY) can be written in capital letters or in lower case. All other custom values will retain the case.
Example:
IO k.43 = UP and IO k.44 = DOWN : CAMERA cam1 = 60
is equivalent to:
io k.43 = up AND io k.44 = down : camera cam1 = 60
Example:
IO k.36 = 1 : UISET message.text = "Stairs light ON"
The text “Stairs light ON” remains unchanged.
Spaces and not-relevant tabulation characters are ignored.
In some cases separation spaces are not necessary:
IO k.36=1
is a valid expression, while
IOk.36 = 1
is not valid because the keywords must be separated by their attributes.
The EVENTS interpreter tries to understand strings even when not enclosed in double quotes, but we consider a good practice to always use double quotes to delimit text strings, and this may even become mandatory in future releases.
Example:
IO k.36 = 1 : LOG = "I turn on the light: 36"
Stable and transient events
IO k.33
is a transient event. It occurs only during the status change of the actuator with data point name k.33. If it is part of a complex expression, it will be true only when the expression evaluation is triggered by that specific change event, and will be false when the expression evaluation is triggered by any other event. For example:
IO k.33 AND IO k.33
is an event that will never occur, because two transient events can never be simultaneously true.
A stable event is value based condition. For example:
IO k.33 > 40
is a stable event. It occurs when the status value of actuator k.33 is greater than 40 (more than 40% of a dimmer level).
Unlike the transient events, this expression is true anyway, even after the transient event, so:
IO k.33 > 40 AND IO k.34 > 40
is an event that may occur when both the actuators k.33 and k.34 are on with a level greater than 40%.
In some cases it would be necessary to use a transient event associated to a device, also combined with status expressions of the device itself.
Example:
IO k.33 = 1 AND IO k.34 = 1 AND NOT IO k.33
The expression NOT IO k.33 excludes the events generated from any status change of device k.33. Meanwhile IO k.33 = 1 makes the expression true only when the device status is ON.
As a result, this event occurs when the devices k.33 and k.34 are simultaneously ON, but only on the status change of device k.34, and ignoring the status change of device k.33.
Example:
IO k.33 = 1 AND IO k.34 = 1 AND NOT IO k.33 : IO k.33 = 0, WAIT = 0.5, IO k.33 = 1
If light k.33 is already ON, as soon as light k.34 is turned on, light k.33 will flash once.
By omitting the expression NOT IO k.33 the light wouldn’t stop blinking because the action would trigger the same event again and again.
One Event, More Rules
You can define several rules referencing the same event.
When HSYCO detects any status change in the system, it scans EVENTS for all event expressions that could be affected by that event. All relevant expression are then evaluated and, if true, the associated lists of actions are executed.
This process is normally performed top-down on the events.txt file, but the execution order is not guaranteed.
Example:
IO k.34 = 1 : IO k.36 = 0 IO k.34 = 1 AND DAY : IO k.37 = 0
When the actuator k.34 is turned on, these rules cause actuator k.36 to go off, while the actuator k.37 will be turned off only during the day.
Actions
You can associate multiple, comma separated actions to each event. For example:
NIGHT : IO k.33 = 1, IO k.34 = 1, IO k.88 = UP
In order to speed up the writing and make rules clearer, many commands let you specify a list of addresses as attributes of the command. The rule written above can be rewritten in a shorter form as:
NIGHT : IO k.33 k.34 = 1, IO k.88 = UP
Each event : action rule is normally written on a single line. However the readability can be improved by typing the list of actions on following lines, after adding a comma at the end of the preceding lines. It Is also possible to write only the event expression on the first line, followed by : and start the list of actions in the following line:
NIGHT : IO k.33 k.34 = 1, IO k.86 k.87 k.88 = UP
The event expression can’t be written on more than one line.
Variables
Variables are identified by any text name starting with the character $. For example:
$level
Variable names are case insensitive, so $level and $LEVEL are the same variable. Only letters and numbers are allowed, no special characters.
A variable can be assigned any value and doesn’t need to be declared before being used.
Variables and Actions
Variables can be assigned constant values or expressions results:
HSYCOSTART : $count = 0
assigns the value 0 to the variable $count as soon as HSYCO starts.
The basic arithmetic operations (+, -, * and /), the division’s reminder (%) and rounding to an arbitrary1 number of digits (ROUND n) are supported.
A variable text can be appended to another text by simply using the + operator. This automatically performs a string append only if the variable original content or the operand are not numerical.
Example:
IO k.33 = 1 : $count + 1
increases by 1 the value of $count any time the actuator k.33 is turned on.
Example:
$voltage : $rv = $voltage, $rv ROUND 2
the $rv variable is set to the value of $voltage, rounded to 2 decimal digits.
Example:
IO k.33 = 1 : $count + 1, $count % 4
like the previous example, but it also computes the modulo of 4 of the variable, writing back the result in the variable itself. This way this variable will be increased up to 3, before turning into 0 again.
To delete a variable, assign an empty string to it:
IO k.33 = 0 : $status = ""
When appending strings, more than one string can be written after the equals sign or, in general, after the operator. In this case the strings will be concatenated.
This is particularly useful when assigning a complex text to a variable.
Example:
time : $body = "The daily power consumption " $date:y/m/d$ " at " $time:h:m:s$ " is " $power$ " Watt"
You can also apply a decimal number format pattern to variables, using the FORMAT “pattern” operator.
A pattern contains a positive and negative sub-pattern, for example, "#,##0.00;(#,##0.00)". Each sub-pattern has a prefix, numeric part, and suffix. The negative sub-pattern is optional; if absent, then the positive sub-pattern prefixed with the localized minus sign ('-' in most locales) is used as the negative sub-pattern. That is, "0.00" alone is equivalent to "0.00;-0.00".
The # symbol represents a digit that is not shown when that digit is zero. The 0 symbol represents a digit that is always shown. For more information on the pattern format, see the java.text.DecimalFormat2 class documentation.
The pattern can also be prefixed with a two letter country or language id and a colon character, for example, “EN:#,##0.00”. In this case the pattern and the resulting format is localized based on the country or language id. If the localization id is not present, the format operator uses the localization rules of the Language parameter in hsyco.ini.
Example:
$voltage : $rf = $voltage, $rf FORMAT "#.00"
the $rf variable is set to the value of $voltage, always showing the two most significant decimals, even if the number is integer.
Example:
$voltage : $rf = $voltage, $rf FORMAT "IT:#,00"
the $rf variable is set to the value of $voltage, always showing the two most significant decimals, and using the Italian localization rules, with the comma character as decimal separator.
Variables and Events
Variables can be part of event expressions, so you can compare the content with constant values or another variable, or compare a device status with the value of a variable.
The comparison operators are:
= > < >= <= *=
*= is a contains operator, matching any left-side string that contains the right-side string.
The comparison is based on numeric values if both operands are numerical, otherwise it is text based, ignoring the difference between upper and lower case letters. If one of the two operands is a number and the other is "off", the number is compared with 0. For example:
HSYCOSTART : $count = 0 IO k.33 = 1 : $count + 1 $count : LOG="Increase the count to value: " $count $count = 10 : LOG="Tenth turning on of light 33"
An event defined just with the variable name, thus omitting the comparison operator, is a transient event which will occur when the variable status changes, regardless of its value.
It is possible to verify if a variable is defined. The event condition:
$varname = ""
is true if the variable is not defined or if has been explicitly set to "".