-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
root
committed
Jun 8, 2018
1 parent
956f796
commit b6ad955
Showing
4 changed files
with
464 additions
and
194 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,263 @@ | ||
Item scripts | ||
============ | ||
|
||
Item scripts are used to update :doc:`items'<items>` state and execute actions. | ||
Scripts are placed in xc folder (**xc/uc** for `/uc/uc`, **xc/lm** for | ||
`/lm/lm`) and may be either written in any scripting language or be binary | ||
executables. The script file should have exec permissions. | ||
|
||
All the examples provided in this documentation are written in the classic | ||
Bourne shell (bash). It is recommended to use dash or perl in the heavy loaded | ||
production systems to provide better startup speed. Experience has shown that | ||
the modern systems do not require the use of the lower-level languages compiled | ||
into executable files: it complicates the integration and servicing, on the | ||
other hand, the difference in the program operation is only a few milliseconds. | ||
|
||
The script always the max execution time (timeout) specified in the item | ||
configuration (or default controller timeout). After that the system terminates | ||
the script operation: firstly - voluntary, by sending SIGTERM, then - forcibly | ||
by sending SIGKILL (this in-between time may be changed in the item | ||
configuration with param *term_kill_interval*) | ||
|
||
Script or program always gets the environment variables: | ||
|
||
* all variables from the controller var file (:ref:`uc_cvars<uc_cvars>` or | ||
:ref:`lm_cvars`<lm_cvars>`) | ||
* **PATH** variable with additional EVA bin and xbin subfolders | ||
* **EVA_ITEM_ID** item ID which the script is being executed for | ||
* **EVA_ITEM_TYPE** item type: unit, sensor or lvar, (lvars can also be | ||
updated with a scripts) | ||
* **EVA_ITEM_GROUP** full item group | ||
* **EVA_ITEM_PARENT_GROUP** nearest parent group of the item (i.e. | ||
building1/env/room1/temp1 - room1) | ||
* **EVA_ITEM_FULL_ID** full item ID | ||
* **EVA_ITEM_STATUS** current item status | ||
* **EVA_ITEM_VALUE** current item state value | ||
|
||
The system considers the script to be successful if its exit code is 0. | ||
|
||
Item actions | ||
~~~~~~~~~~~~ | ||
|
||
Item actions are used to control the units. After the :ref:`unit<unit>` action | ||
has ben called, the controller executes the appropriate script. By default, | ||
control scripts are placed in xc/uc/ folder and named ID, where ID is a unit | ||
ID, for example, xc/uc/lamp1. This may be changed in the item configuration to | ||
let i.e. one script execute actions for the group of units. | ||
|
||
The startup parameters of the action script include: | ||
|
||
* **param1** unit ID | ||
* **param2** new unit status | ||
* **param3** new unit value | ||
|
||
A simple example script: send toe command to `X10 | ||
<https://en.wikipedia.org/wiki/X10>`_ controller via `mochad | ||
<https://sourceforge.net/projects/mochad/>`_ | ||
|
||
.. code-block:: bash | ||
#!/bin/sh | ||
[ $2 -eq 0 ] && CMD="off" || CMD="on" | ||
echo "pl $1 $CMD" | nc localhost 1099 | ||
Such script is actually universal for X10 (in case units are named according to | ||
X10 - a1-aX) | ||
|
||
Another example: activate the third `EG-PM2-LAN | ||
<http://energenie.com/item.aspx?id=7557>`_ plug. Here we access EG1_IP variable | ||
from :ref:`uc_cvars<uc_cvars>` | ||
|
||
.. code-block:: bash | ||
#!/bin/sh | ||
EG-PM2-LAN $EG1_IP 3 $2 | ||
Another example: control the relay (4 modules, 1 relay block) by `Denkovi | ||
AE <http://denkovi.com/relay-boards>`_ | ||
|
||
.. code-block:: bash | ||
#!/bin/sh | ||
${RELAY1_CMD}.1.4.0 i $2 | ||
where in :ref:`uc_cvars<uc_cvars>`: | ||
|
||
.. code-block:: bash | ||
RELAY1_CMD = snmpset -v1 -c private RELAY_IP_ADDRESS .1.3.6.1.4.1.19865.1.2 | ||
In the previous examples, we used the same command for turning the units | ||
on/off. Let us review more complex logic. The next example shows how EVA can | ||
shut down the remote server machine and turn it on via Wake on LAN (tip: such | ||
script requires more action_timeout in unit config): | ||
|
||
.. code-block:: bash | ||
#!/bin/sh | ||
case $2 in | ||
0) | ||
ssh eva@${SERVER_IP} "sudo /sbin/poweroff" | ||
;; | ||
1) | ||
wakeonlan ${SERVER_MAC} | ||
;; | ||
esac | ||
In the :ref:`queue<queues>` history script is marked as completed if it | ||
completed independently with 0 code, failed - if the code differs from 0. | ||
|
||
The script or program can display anything on stdout/stderr. This data, as well | ||
the exit code, will be recorded in "out" and "err" fields of the | ||
:ref:`result<result>` dict. | ||
|
||
Sometimes it is useful to catch SIGTERM in the script/program, i.e. if you | ||
operate the motor that must be stopped after the script gets a termination | ||
signal. Warning:, the system does not track/stop child processes executed after | ||
SIGTERM is sent to the script. | ||
|
||
Passive updates of item state | ||
----------------------------- | ||
|
||
Passive updates are used to collect the state of the equipment which doesn't | ||
report its state by itself. By default, scripts for passive updating of the | ||
item state are named **ID_update**, where ID is a unit ID, for example: | ||
*lamp1_update*. | ||
|
||
The status update script is being executed: | ||
|
||
* Every X seconds, if *update_interval* specified in the config is more than 0 | ||
* After the unit action succeeds (if *update_exec_after_action=true* in config) | ||
|
||
The system considers the script was executed successfully if its exit code is | ||
0, otherwise, its new item state is ignored. | ||
|
||
Passive update scripts get the following parameters: | ||
|
||
* **param1** "update" | ||
* **param2** item ID | ||
|
||
Script should print on stdout only the new status and (optionally) value, | ||
separated by space, i.e. | ||
|
||
0 NEW_VALUE | ||
|
||
For the sensor, it's data should be printed as: | ||
|
||
1 VALUE | ||
|
||
where 1 means the sensor is working properly. | ||
|
||
Let us analyze an example of a simple script, e. g. state update of the sensor | ||
that monitors the remote machine | ||
|
||
.. code-block:: bash | ||
#!/bin/sh | ||
ping -W1 -c1 ${SERVER_IP} > /dev/null 2>&1 && echo "1 1"||echo "1 0" | ||
Unit status - the third `EG-PM2-LAN <http://energenie.com/item.aspx?id=7557>`_ | ||
plug | ||
|
||
.. code-block:: bash | ||
#!/bin/sh | ||
EG-PM2-LAN evacc-rl5|cut -d, -f3 | ||
Update state of the relay (4 modules, 1 relay block) by `Denkovi | ||
AE <http://denkovi.com/relay-boards>`_ | ||
|
||
.. code-block:: bash | ||
#!/bin/sh | ||
${RELAY1_UPDATE_CMD}.2.0|awk -F\ '{ print $4 | ||
where in :ref:`uc_cvars<uc_cvars>`: | ||
.. code-block:: bash | ||
RELAY1_UPDATE_CMD = snmpget -v2c -c public RELAY_IP_ADDRESS .1.3.6.1.4.1.42505.6.2.3.1.3 | ||
Multiupdate scripts | ||
------------------- | ||
:ref:`Multiupdates<multiupdate>` allow updating the state of several items with | ||
the one script which works like a normal passive update script and outputs the | ||
states of the monitored items line-by-line: | ||
.. code-block:: bash | ||
item1_status item1_value | ||
item2_status item2_value | ||
..... | ||
The order of the output should correspond to the order of the items in the | ||
multiupdate. | ||
By default, multiupdate scripts are named **ID_update**, where ID is a | ||
multiupdate ID, for example, *xc/uc/temperatures_update* for mu ID = | ||
temperatures. | ||
For example, let's update all 8 units connected to the relay controlled by | ||
`DS2408 <https://datasheets.maximintegrated.com/en/ds/DS2408.pdf>`_ | ||
|
||
.. code-block:: bash | ||
#!/bin/sh | ||
w1_ds2408 28-999999999999 || exit 1 | ||
The script output will be as approximately follows: | ||
|
||
.. code-block:: bash | ||
1 | ||
0 | ||
1 | ||
1 | ||
1 | ||
1 | ||
0 | ||
1 | ||
where each row contains the status of the unit connected to the corresponding | ||
relay port. | ||
|
||
Commands | ||
-------- | ||
|
||
Commands are used if you need to run some commands remotely on the server where | ||
EVA controller is installed. Commands are executed with :doc:`controller cli | ||
tools</cli>`, with SYS API function :`ref`:`cmd<cmd>` or with :ref:`macro | ||
function<m-cmd>`. | ||
|
||
For command scripts: | ||
|
||
* Configurations are absent. Scripts are named as **xc/cmd/SCRIPT_NAME** | ||
* Script timeout is set when it is started | ||
|
||
Example of a command usage: the speaker is connected to the remote machine. we | ||
want to play some sound as an additional feedback after the certain macros or | ||
actions are executed | ||
|
||
**xc/cmd/play_snd** | ||
|
||
.. code-block:: bash | ||
#!/bin/sh | ||
GAIN=-7 | ||
killall play > /dev/null 2>&1 && killall -9 play > /dev/null 2>&1 | ||
play /data/snd/$1.wav gain ${GAIN} | ||
when you call the command, the sound file_name will be played. If you want to | ||
wait until the playback is over add w=15 to API call i.e. to wait 15 seconds | ||
before continue. | ||
|
Oops, something went wrong.