SCADA Final Aggregator

SCADA Final Aggregator (SFA) is a subsystem usually installed directly in the host wherein the user interface or third-party applications are installed.

It aggregates all the control and monitoring items, logic macros and decision rules from all connected UC and LM PLC controllers into one place. As a result, the final interface or application doesn’t need to know on which controller the item is present, it does all the function calls directly to SFA. Ids of the items should be always specified in oid form (type:group/id) and be unique in the whole installation.

SCADA Final Aggregator

Example of the controller aggregation with the use of two SFA servers

SFA is set up and controlled with eva sfa console application and SFA API. The API doesn’t have a user interface by default, it’s developed specifically for certain installation certain installation using SFA Templates (server-side part) and EVA JS Framework (client-side part).

All changes of item status, actions, and logs are sent to the notification system. In addition, SFA can function as the notification aggregator e. g. by transferring MQTT messages to other application via HTTP or redirecting them to other MQTT servers. SFA usually has several or all available controllers connected. At least one MQTT server should be installed in the setup to let it work in real time.

Since SFA is a part of EVA platform, its operating principles, settings, and configuration files generally match the other components.

etc/sfa.ini configuration file

sfa.ini - primary configuration file of SFA

; system name (default - hostname)
; name = eva3-sfa1
; system polldelay
polldelay = 0.01
; pid file (default var/
pid_file = var/
; log file
log_file = log/sfa.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
; 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 updates - instant, manual or on_exit
db_update = instant
; db file, default runtime/db/sfa.db
db_file = runtime/db/sfa.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
; keep action history in seconds
; 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/ /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
; 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)
stop_on_critical = yes
; default timeout
timeout = 5

; 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

; 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 =
;domain =
;key_prefix =
;ou = EVA
;ca = /path/to/ca-file.crt

; discover controllers via UPnP on all interfaces, or list, comma separated
discover_on = all

; enable remote file management functions
;file_management = yes
; allow entering setup mode
setup_mode = 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
; note: SFA Framework will not work without sessions
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 use frontend X-Real-IP header to get client real IP address
;x_real_ip = yes

; enable cloud manager services
;cloud_manager = yes
;default_key = default

runtime/sfa_cvars.json variables file

sfa_cvars.json - file containing user variables. All SFA user variables are directly available in SFA Templates and EVA JS Framework after login with any valid user or API key.

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 sfa cvar get and cvar set commands.

etc/sfa_apikeys.ini API keys file

API access keys are stored into etc/sfa_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 the full access to the system similar to root user (or the user SFA 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
;pvt = #
;rpvt =
;hosts_allow =
; key will be assigned to requests from these hosts if no key provided
;hosts_assign =

;key = key2secret
;items = macro1, lvar1, lvar2
;sysfunc = yes
;allow = cmd
;pvt = dir1/#, file1, dir2/file2, dir3/+/content.js
;rpvt =
;hosts_allow =

Connecting UC and LM PLC controllers

SFA works only with the items known to the controller. Prior to connecting UC and LM PLC remote controllers, it is necessary to connect SFA to MQTT server (via its notification system), to which other controllers will send the events. SFA reads the list of items, macros, rules and the initial item status from the connected controllers; further status updates are performed via MQTT.

For timers to be displayed correctly in the user interface, it is important to maximally synchronize the system time between LM PLC and SFA, if LM PLC controllers are set up on the remote servers.

To connect the controllers you should use eva sfa (sfa-cmd) console command or SFA API append_controller function.

When connecting, it is necessary to indicate minimum URI of the connected controller and API KEY functioning either as a master key or the key with access to certain items. If Logic Manager and UC keys are the same, the key can be set as $key (\$key in the command line). In this case, LM will use the local key of its own configuration.

eva sfa append_controller -u http://localhost:8812 -a secretkey -y
eva sfa append_controller -u http://localhost:8817 -a secretkey -y

You may specify a controller type with -g argument (-g uc or -g lm). If the group is not specified, SFA tries to automatically detect the remote controller type.

Configurations of the connected controllers are stored in the folder runtime/sfa_remote_uc.d/ for UC and runtime/sfa_remote_lm.d/ for LM PLC.

SFA automatically loads the connected controller data (its id) and saves the configuration to runtime/sfa_remote_<type>.d/<ID>.json.

Items from remote controllers are loaded at the SFA start and then refreshed with reload_interval frequency set individually for each connected controller. If SFA fails to get the item list during loading, it will use the existing one.

To control the list of the received items you can use eva sfa or SFA API function list_remote:

eva sfa remote -p unit
eva sfa remote -p sensor
efa sfa remote -p lvar

The available logic macros are listed by the command

eva sfa macro list


Macros from system group and its subgroups are not loaded to SFA

All connected controllers have the following properties that can be changed while SFA is running:

  • description optional description of the controller
  • key API key used to access the connected controller
  • mqtt_update MQTT notifier through which items update their status
  • reload_interval interval (seconds) to reload the item list from the server, 0 - load the list only at the start
  • ssl_verify either verify or not the SSL certificate validity when working through https://. May be True (verify) or False (not verify) The certificate is verified by default.
  • timeout request timeout (seconds)
  • uri API URI of the connected controller (proto://host:port, without /uc-api/ or /lm-api/)

Parameters are displayed with eva sfa command or SCADA Final Aggregator list_controller_props function, modified with set_controller_prop. Function list_controllers displays the list of all connected controllers.

To remove the connected controller use remove_controller function.

When managing the connected controllers, ID should be always provided in the full format: controller_type/ID (i.e. uc/controller1).


SFA interface is always specifically designed for a certain installation using SFA Templates, EVA JS Framework and SFA PVT. Interface files are stored in ui folder, interface is available at http(s)://<IP_address_SFA:Port>/ (redirects to /ui/) or http(s)://<IP_address_SFA:Port>/ui/.

Startup and shutdown

To manage SFA controller server, use:

  • eva sfa server start start SFA server
  • eva sfa server stop stop SFA server
  • eva sfa server restart restart SFA server
  • eva sfa 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.