Universal Controller

EVA Universal Controller (UC) is a control and monitoring subsystem.

It should be installed if you actually want to control something. UC is controlled via UC EI web interface or eva uc (uc-cmd) console application. Additionally, it can be integrated into other subsystems and third-party programs using UC API.

Universal Controller subsystem

You may use Universal Controller independently or integrate it with other EVA subsystems.

Units receive control actions, the controller forms them into queues and executes them using external scripts. If necessary, it terminates the current script and keeps the command history.

Additionally, Universal Controller collects data from the connected items using active and passive status updates.

Universal Controller can control equipment directly and/or act as a gateway for other local controllers.

Item status and values are stored in the local database. Other subsystems or third-party programs can read them using UC API.

Units and sensors are controlled via UC EI interface, configured via UC API. States are controlled and updated using drivers and item scripts.

All changes of item status, current control commands, and progress logs are sent to the notification system.


EVA is a real-time system. Being one of its essential components, UC also follows this rule. The value of poll delay is set in configuration in seconds (milliseconds using dot), e.g. 0.01.

The value of POLL DELAY means that all timeouts and events in the system should fulfill their functions for not more than TIME_SET + POLL DELAY.

Reducing POLL DELAY will increase the CPU load on the server; in turn, if increased, the UC reaction time will be longer. Recommended values: 0.1 for home and office, 0.01 and less - for industrial applications.

The optimum value of POLL DELAY for UC can be set via eva sfa, or by manually calling UC API functions and comparing reaction/execution time of the commands.

The minimum value of POLL DELAY is 0.001 (1 millisecond).

etc/uc.ini configuration file

uc.ini - primary configuration file of UC server

; system name (default - hostname)
; name = eva-uc1
; system polldelay
polldelay = 0.01
; pid file (default var/uc.pid)
pid_file = var/uc.pid
; log file
log_file = log/uc.log
; custom primary log format (use double %)
;log_format = { "loggerName":"%%(name)s", "timestamp":"%%(asctime)s", "pathName":"%%(pathname)s", "logRecordCreationTime":"%%(created)f", "functionName":"%%(funcName)s", "levelNo":"%%(levelno)s", "lineNo":"%%(lineno)d", "time":"%%(msecs)d", "levelName":"%%(levelname)s", "message":"%%(message)s" }
; logging to local syslog
;syslog = yes
; logging to non-standard (/dev/log) local syslog socket
;syslog = /var/run/syslog
; logging to remote syslog
;syslog = hostname:514
; db updates - instant, manual or on_exit
; custom syslog format (use double %)
;syslog_format = EVA: { "loggerName":"%%(name)s", "timestamp":"%%(asctime)s", "pathName":"%%(pathname)s", "logRecordCreationTime":"%%(created)f", "functionName":"%%(funcName)s", "levelNo":"%%(levelno)s", "lineNo":"%%(lineno)d", "time":"%%(msecs)d", "levelName":"%%(levelname)s", "message":"%%(message)s" }
db_update = instant
; db file, default runtime/db/uc.db
db_file = runtime/db/uc.db
; use MySQL instead of SQLite
;db = mysql+pymysql://user:password@localhost/dbname
; user db file, default = db_file
; one user db may be used by multiple controllers at once
;userdb_file = runtime/db/users.db
; use MySQL instead of SQLite
;userdb = mysql+pymysql://user:password@localhost/dbname
; launch external script/program when user is created/got new
; password/destroyed. additional arguments:
;    1) create | set_password | destroy
;    2) user
;    3) password (for create and set_password operations)
;user_hook = /opt/eva/xbin/htpasswd.sh /opt/eva/etc/htpasswd
; keep action history in seconds
keep_action_history = 86400
; action cleaner interval, in seconds
action_cleaner_interval = 60
; keep memory log in seconds
keep_logmem = 86400
; keep extended API call log in user db in seconds (0 = disable logging)
;keep_api_log = 0
; notify state on start
notify_on_start = yes
; debug mode
debug = no
; show error traceback
;show_traceback = yes
; logging level, info, warning, error or critical
;logging_level = info
; create crash dump on critical errors
dump_on_critical = yes
; stop server on critical errors (will be restarted via safe-run)
; always - stop on all critical errors
; core - core errors only (ignore driver critical errors)
; no - don't stop
stop_on_critical = always
; default timeout
timeout = 5
; layout (simple or enterprise)
layout = enterprise

; primary thread pool, min workers. comment to pre-spawn all workers
;pool_min_size = 0
; primary thread pool, max workers. comment to use automatic value (nCPUs * 5)
;pool_max_size = 100
; reactor thread pool size (used by Modbus slave and some utility workers)
;reactor_thread_pool = 15

; exec commands before/after config/db save,
; e.g. mount -o remount,rw / (then back to ro)

;exec_before_save =
;exec_after_save =

; default mqtt notifier for updates for new items
;mqtt_update_default = eva_1:2

; plugins, comma separated
;plugins =

; user authentication via MS Active Directory
;host = ad.yourdomain.com
;domain = yourdomain.com
;key_prefix =
;ou = EVA
;ca = /path/to/ca-file.crt

; allow UPnP discovery of this controller
listen =

; enable remote file management functions
file_management = yes
; allow entering setup mode
setup_mode = yes
; allow rpvt
;rpvt = yes

; web api listen on IP/port
listen =
;ssl_listen =
;ssl_module = builtin
;ssl_cert = test.crt
;ssl_key = test.key
;ssl_chain = test.pam
; session timeout, set to non-zero to enable API session tokens
session_timeout = 3600
; session tokens will expire even if active requests are received
;session_no_prolong = yes
; server thread pool
;thread_pool = 15
; uncomment to disable UC EI
;ei_enabled = no
; uncomment to use frontend X-Real-IP header to get client real IP address
;x_real_ip = yes

; snmp trap handler, default community is eva
listen =
community = eva
; hosts, allowed to send snmp traps
hosts_allow =

; udp api
listen =
; hosts, allowed to send UDP commands
hosts_allow =
hosts_allow_encrypted =

; modbus slave configuration
; first number indicates modbus address (hex or decimal)
; multiple values can be specified
; modbus slave memory space size: 10000 registers (starting from 0) for each
; type (holding, input, coils, discrete inputs)
;tcp0 = 0x01,
;udp0 = 0x01,
; framer for serial: rtu, ascii or binary
;serial0 = 0x01,rtu:/dev/ttyS0:9600:8:N:1
;serial1 = 0x05,rtu:/dev/ttyS1:9600:8:N:1

runtime/uc_cvars.json variables file

uc_cvars.json - file containing user variables passed to all commands and item scripts within the system environment.

The file contains a JSON dict:

 "VAR1": "value1",
 "VAR2": "value2"

Variables can be changed while the server is running via SYS API as well as eva uc cvar_get and cvar_set commands.

For example, let’s create a variable:

eva uc cvar set RELAY1_CMD "snmpset -v1 -c private ."

After UC is started, it will become available for system environment, and unit management script on the port 2 of the given relay will be the following:

${RELAY1_CMD}.1.2.0 i $2

It’s possible to assign different values for the variables used for different object groups with the same names, e.g. group1/VAR1, group2/VAR1 etc. In this case the variable will be available only for the specified group.

etc/uc_apikeys.ini API keys file

API access keys are stored into etc/uc_apikeys.ini file. At least one full access key named masterkey should be present for proper functioning. Important: with master key and API anyone can receive full access to the system similar to root user (or the user UC is run under), that is why it is recommended to use this key only in supervisory networks or even restrict its use to local host only.

; the default master key is eva, change it!
key = eva
master = yes
hosts_allow =

;key = key1secret
;groups = group1/#, group2, group3/+/somegroup
;hosts_allow =

;key = key2secret
;items = unit1, unit2
;sysfunc = yes
;allow = cmd, lock, device
;hosts_allow =
; key will be assigned to requests from these hosts if no key provided
;hosts_assign =

;key = lmsecret
;groups = #
;sysfunc = yes
;allow = cmd
;hosts_allow =,

;key = sfasecret
;groups = #
;hosts_allow =,

Action queues

All the unit control actions are queued right after they’re created. Item status update actions are not queued and just run in accordance with the set intervals.

Before execution, the control action is placed in two queues:

  • global queue for all actions
  • certain unit queue

All actions have their “priority” set when they are generated. The default priority is 100. The lower means the higher priority of queued action execution.

Queued action can have the following status:

  • created action has just been created and has not been queued yet
  • pending the action is placed in the global queue. The previous action status, as well as this one, are rarely found because UC API waits for the command to be placed in the queue of a certain unit and then returns the result
  • queued the action has already passed the global queue and is now waiting to be executed in the queue of a certain unit
  • refused unit rejected the action execution because of the item configuration value action_enabled=False
  • dead API failed to wait until the action is placed to the queue of a certain unit and, therefore, marked it as “dead”. Virtually, such status clearly indicates that server is seriously overloaded
  • canceled the command is canceled either from the outside or due to either unit already running the other action (in case action_queue=0 and queue is disabled) or the unit has got new action to execute and action_queue=2 (cancel and terminate the pending actions after getting a new one)
  • ignored the unit rejected the action execution, because its status/value are the same as requested to be changed to, and action_always_exec=False
  • running the action is being executed
  • failed the controller failed to execute the command
  • terminated the controller terminated the action execution due to timeout or by the external request
  • completed the action finished successfully

Startup and shutdown

To manage UC controller server, use:

  • eva uc server start start UC server
  • eva uc server stop stop UC server
  • eva uc server restart restart UC server
  • eva uc server reload restart controller only (without watchdogs)

The controller startup/shutdown is also performed by ./sbin/eva-control which is configured during the system setup.