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 ICS 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.

config/sfa/main registry key

config/sfa/main registry key contains the controller configuration.

  # system poll delay
  polldelay: 0.01
  # pid file
  pid-file: var/
  # log file
  log-file: log/sfa.log
  # custom primary log format
  #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: true
  # logging to non-standard (/dev/log) local syslog socket
  #syslog: /var/run/syslog
  # logging to remote syslog
  #syslog: hostname:514
  # custom syslog format
  #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: 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 simultaneously
  #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/ /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
  # minimal log level
  #logging-level: warning
  # keep extended API call log in user db in seconds (0 = disable logging)
  #keep-api-log: 0
  # notify states on start
  notify-on-start: true
  # debug mode
  debug: false
  # log code tracebacks
  #show-traceback: true
  # create crash dump on critical errors
  dump-on-critical: true
  # 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)
  # false - don't stop
  stop-on-critical: always
  # default timeout
  timeout: 5
  # default suicide timeout (kill -KILL process on shutdown)
  #suicide-timeout: 30
  # 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: "mount -o remount,rw /"
  #exec-after-save: "mount -o remount,ro /"
  # default mqtt notifier for updates for new items
  #mqtt-update-default: "eva_1:2"
  # auto-save created items
  auto-save: true
# LURP replication
#  listen:
#  buffer: 32768
  # user authentication via MS Active Directory
  #key-prefix: ""
  #ou: EVA
  #ca: /path/to/ca-file.crt
  # cache credentials for the specified time (seconds)
  # default: 86400 (1 day), 0 to disable caching
  #cache-time: 86400
  # allow UPnP discovery of this controller
  # discover controllers via UPnP on all interfaces, or list
  discover-on: all
  # enable remote file management functions
  file-management: true
  # allow entering setup mode
  setup-mode: true
  # web api listen on IP/port
  #ssl-module: builtin # or pyopenssl
  #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: true
  # server thread pool
  #thread-pool: 15
  # disable UC EI
  #ei-enabled: false
  # use frontend X-Real-IP header to get client real IP address
  #x-real-ip: true
  # override real ip header name
  #real-ip-header: X-IP
  # enable/disable cloud manager
  cloud-manager: false
  # default API key ID
  default-key: default
  # discover controllers as static
  #discover-as-static: true

Custom variables

Custom variables can be changed while the server is running via Common methods as well as eva sfa cvar_get and cvar_set commands.

All SFA custom variables are directly available in SFA Templates and EVA ICS JS Framework after login with any valid user or API key.

Variables can be changed while the server is running via Common methods as well as eva sfa cvar get and cvar set commands.

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 ICS 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.