Installation

All you need to install EVA is to download the latest update from https://www.eva-ics.com/, unpack the archive to any folder and everything is almost ready to use.

Note

Each EVA ICS installation (node) can run multiple components. Despite they share node resources, they still act as independent processes and require inter-connection set up.

System Requirements

Important

Before installation, set the proper host name. It will be used to identify node controllers. Changing host name later will require manually removing/appending all static links between EVA ICS controllers.

  • Python version 3 (3.4+)
  • Python virtual environment modules (python3-virtualenv)
  • Linux or UNIX-compatible system
  • For SFA PVT to work with images: libjpeg-dev and libjpeg8-dev (for PIL / pillow installation)
  • realpath (available in all modern Linux distributions)
  • EVA ICS can run on any Linux or UNIX-compatible system, but for the smooth install we recommend Ubuntu or Debian.
  • Install system package libow-dev to let EVA ICS install owfs module.
  • To sync item status between the controllers in different networks - MQTT-server (e.g. mosquitto) or to communicate with other equipment and 3rd party software.

Warning

Installation scripts try to install all required Python modules automatically, but some of them can have problems installing with pip - install can fail or be slow. It’s better to install these modules manually, before running EVA installation scripts. Currently the problems can be expected on ARM systems with:

  • pandas (python3-pandas)
  • cryptography (python3-cryptography)

To let EVA ICS venv use system site modules, read instructions below.

Optional modules (can be disabled in venv configuration):

  • onewire required for 1-Wire via OWFS
  • pymodbus required for Modbus master/slave functions
  • pysnmp required for SNMP client/server functions
  • pillow required for SFA PVT image processing

Using installer

Supported Linux distributions:

  • Debian/Ubuntu/Raspbian
  • Fedora

Automatic and unattended

Install required system packages, setup EVA ICS components:

sudo -s
curl geteva.cc | sh /dev/stdin -a

Customized

Customize API keys:

sudo -s
curl geteva.cc | env MASTERKEY=123 DEFAULTKEY=qwerty sh /dev/stdin -a

More options, interactive setup:

sudo -s
curl geteva.cc -o install.sh
sh install.sh --help

E.g. install required system packages, setup Universal Controller only, use external MQTT server and predefined API keys:

sudo -s
curl geteva.cc | \
    env MASTERKEY=mykey DEFAULTKEY=mydefaultkey sh /dev/stdin \
        --autostart --logrotate --bash-completion \
        -- --auto -p uc --mqtt eva:password@192.168.1.100 --mqtt-announce --mqtt-discovery

Manual installation

Note

If you are going to run any controllers under restricted user account, make sure it has a valid shell set.

Preparing the system

Install required system packages and heavy Python modules from the OS repository. here is an example how to install them on Debian-based Linux (i.e. Ubuntu):

apt install -y curl gcc python3 python3-dev python3-virtualenv python3-distutils jq libow-dev libjpeg-dev libjpeg8-dev

Configuring MQTT broker

MQTT broker is used when EVA ICS controllers are located in different networks and can not exchange data with P2P connections.

Note

Starting from EVA ICS 3.2.3, MQTT broker for inter-connection of controllers which run on a single host/network is no longer required.

If EVA ICS node is already set up without MQTT configuration, you can add it later with easy-setup or manually, using eva ns command.

Installing local MQTT server

If you plan to use local MQTT server, here is an example how to install mosquitto MQTT server on Debian-based Linux (i.e. Ubuntu):

apt install -y mosquitto
# stop mosquitto
/etc/init.d/mosquitto stop
# let the server listen to localhost only
echo "bind_address 127.0.0.1" >> /etc/mosquitto/mosquitto.conf
# start mosquitto back
/etc/init.d/mosquitto start
# make sure mosquitto is running
ps auxw|grep mosquitto

Options for EVA ICS:

  • MQTT host: localhost
  • MQTT port: 1883 (default)
  • MQTT user, password: leave empty
  • MQTT space: leave empty
  • MQTT SSL: leave empty (answer ‘n’ if using easy-setup)

Cloud service provider as MQTT broker

Note

Cloud IoT services provide restricted broker functionality and don’t guarantee event/message ordering. This means some state messages between controllers may be lost (discarded by controller core if newer message with the same topic is already received).

Downloading and extracting EVA ICS distribution

Go to EVA ICS website, download most recent distribution and unpack it e.g. to /opt/eva:

cd /opt
curl https://get.eva-ics.com/3.x.x/stable/eva-3.x.x-xxxxxxxxxx.tgz -o eva.tgz
tar xzvf eva.tgz
mv eva-3.x.x eva
cd eva

Customizing Python virtual environment

Starting from 3.2.1, EVA ICS uses Python virtual environment (venv). This makes software installation more stable, as it uses only tested versions of 3rd party libraries.

EVA ICS installation script automatically creates Python virtual environment in ./python3 folder. It can be customized/recreated later manually, using command:

./install/build-venv

If you want to rebuild venv from scratch, delete python3 folder completely.

On some systems (e.g. ARM-based computers) venv installation can be tricky: you can expect slow installation time or problems with some heavy modules (e.g. pandas, cryptography).

To solve this:

  • If you already run the installation and it has failed, delete ./python3 folder.

  • Go to ./etc folder, copy venv-dist to venv and customize virtual environment options.

    • USE_SYSTEM_PIP=1 allows to use system-installed pip3 (apt-get install python3-pip) in case installation script has a problems downloading / installing it.
    • SYSTEM_SITE_PACKAGES=1 virtual environment will use system site packages if their versions match with requested.
    • SKIP here you can specify the packages (in quotes, space separated), which should be skipped (e.g. pandas cryptography and install it with apt-get install python3-pandas python3-cryptography instead). To let venv use system package, SYSTEM_SITE_PACKAGES=1 should also be present.
    • EXTRA extra modules to install, e.g. required by PHIs, used by logic macros or macro extensions etc.
    • PIP_EXTRA_OPTIONS specify extra options for pip3, e.g. -v for verbose installation.

Note

Customize venv only if you have serious problems installing EVA ICS with default options, as the system may became unstable when versions of 3rd party libraries are different from tested.

Options, specified in ./etc/venv are also used by EVA ICS update scripts, which check/rebuild venv on every system update.

Installing

Warning

If you want to run some components under restricted users, create var and log folders in EVA installation dir and make sure the restricted users have an access to these folders before running easy-setup. If you’ve customized ini files in etc, make sure the restricted user has an access to both <component>.ini and <component>_apikeys.ini.

If you want to make some initial customization, e.g. name the controllers different from the host name, make changes in etc/uc.ini, etc/lm.ini and etc/sfa.ini configs first.

  • For the interactive setup, run ./easy-setup in EVA folder and follow the instructions.
  • For the automatic setup, run ./easy-setup -h in EVA folder and choose the installation type.

Setup log rotation by placing etc/logrotate.d/eva-* files to /etc/logrotate.d system folder. Correct the paths to EVA files if necessary.

cp ./etc/logrotate.d/eva-* /etc/logrotate.d/

Setup automatic launch at boot time by placing EVADIR/sbin/eva-control start command into system startup e.g. either to /etc/rc.local on System V, or for systems with systemd (all modern Linux distributions):

cp ./etc/systemd/eva-ics.service /etc/systemd/system/
systemctl enable eva-ics

Unicode

EVA ICS supports unicode out-of-the-box. If your system has problems, rebuild locales and then restart EVA ICS controllers:

sudo dpkg-reconfigure locales
sudo eva server restart

Updating

Warning

Before updating from the previous version, read update manifest.

Using EVA Shell

  • Backup everything in system shell
  • Launch EVA Shell (/opt/eva/bin/eva-shell or eva -I)
  • Backup configuration (type backup save command in EVA Shell)
  • Type update command in EVA Shell

Note

EVA ICS repository URL has been changed to https://get.eva-ics.com. If you’ve got “Update completed” message but update process hasn’t even been started, try executing update command specifying EVA ICS repository directly:

update -u https://get.eva-ics.com

Using system shell

  • Backup everything
  • Run the following command:
curl -s <UPDATE_SCRIPT_URL> | bash /dev/stdin
#e.g.
#curl -s https://get.eva-ics.com/3.2.4/stable/update.sh | bash /dev/stdin
  • If updating from 3.0.2 or below, you may also want to enable controller watchdog (copy etc/watchdog-dist to etc/watchdog and edit the options if required)

Note

The system downgrade is officially not supported and not recommended.

Intermediate versions

It is usually absolutely safe to update old EVA ICS installations to newer version without applying all intermediate updates.

However, it is highly recommended to read update manifests for all skipped versions and combine before / after update instructions.

Moving to another folder

EVA ICS doesn’t depend on any system paths, this allows to easy rename or move its folder or clone the installation. Just do the following:

  • stop EVA ICS (./sbin/eva-control stop)
  • rename, move or copy EVA ICS folder
  • if you’ve copied the folder, edit configuration files to make sure components use different ports and/or interfaces
  • start EVA ICS back (./sbin/eva-control start)
  • correct logrotate and on-boot startup paths

Watchdog

Watchdog process is started automatically for each EVA controller and tests it with the specified interval. Controller should respond to API call test within the specified API timeout or it is forcibly restarted.

Watchdog configuration is located in file etc/watchdog and has the following params:

  • WATCHDOG_INTERVAL checking frequency (default: 30 sec)
  • WATCHDOG_MAX_TIMEOUT maximum API timeout (default: 5 sec)
  • WATCHDOG_DUMP if the controller is not responding, try to create crash dump before restarting (default: no).

How to assign IDs to items

All system items including macros have their own ids. Item id should be unique within one server in simple layout. When using enterprise layout, it is possible for items to have the same id in different groups, however full item id (group/id) should be always unique within one controller.

Note

Before adding items, consider what kind of layout you want to use: simple or enterprise

Starting from 3.2.0, default item layout is enterprise.

Item groups can coincide and often it is convenient to make them similar: for example, if you set groups=security/# in API key config file, you will allow the key to access all the items in the security group and its subgroups regardless of whether it is macro, sensor or logic variable. To set access to a group of particular items, use oids, e.g. groups=sensor:security/#.

This does not apply to decision rules and macros: a unique id is generated for each rule automatically, macro id should be always unique.

Note

The triple underline (___) is used by system and should not be used in item IDs or groups.

Log file customization

Perform these on the installed Python modules to avoid any extra information in logs:

  • dist-packages/ws4py/websocket.py and dist-packages/ws4py/manager.py - replace all logger.error calls to logger.info

  • dist-packages/urllib3/connectionpool.py - if you set up the controllers to bypass SSL verifications (don’t do this on production!), remove or comment

    if not conn.is_verified:warnings.warn((….

Using NGINX as a frontend for SFA interface

External authentication

Suppose NGINX operates on 8443 port with SSL, and SCADA Final Aggregator - without SSL. Let’s make the task even more complicated: let NGINX receive the request not directly, but via port forwarding from the router listening on an external domain (i.e. port 35200).

Additionally, we want to authorize:

  • by IP address or
  • basic auth by username/password or
  • by cookie-token (required for EVA Android Client since it passes basic auth only when the server is requested for the first time)

The server should allow access upon the authorization of any type.

Our final config for all of this should look like:

map $cookie_letmein $eva_hascookie {
  "STRONGSECRETRANDOMTOKEN" "yes";
  default           "no";
}

geo $eva_ip_based {
  192.168.1.0/24 "yes"; # our internal network
  default        "no";
}

map $eva_hascookie$eva_ip_based $eva_authentication {
  "yesyes" "off"; # cookie and IP matched - OK
  "yesno"  "off"; # cookie matched, IP did not - OK
  "noyes"  "off"; # cookie did not match, IP did - OK
  default  "?"; # everything else - demand the password
}

upstream eva-sfa {
        server 127.0.0.1:8828;
}

server {
    listen 192.168.1.1:8443;
    server_name  eva;
    ssl                  on;
    ssl_certificate /opt/eva/etc/eva.crt;
    ssl_certificate_key /opt/eva/etc/eva.key;
    ssl_session_timeout  1m;
    ssl_protocols  SSLv3 TLSv1;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;

    # proxy for HTTP
    location / {
        auth_basic $eva_authentication;
        auth_basic_user_file /opt/eva/etc/htpasswd;
        add_header Set-Cookie "letmein=STRONGSECRETRANDOMTOKEN;path=/";
        proxy_buffers 16 16k;
        proxy_buffer_size 16k;
        proxy_busy_buffers_size 240k;
        proxy_pass http://eva-sfa;
        # a few variables for backend, though in fact EVA requires X-Real-IP only
        proxy_set_header X-Host $host;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Frontend "nginx";
        proxy_redirect http://internal.eva.domain/ui/ https://external.eva.domain:35200/ui/;
    }

    # proxy for WebSocket
    location /ws {
        auth_basic $eva_authentication;
        auth_basic_user_file /opt/eva3/etc/htpasswd;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffers 16 16k;
        proxy_buffer_size 16k;
        proxy_busy_buffers_size 240k;
        proxy_pass http://eva-sfa;
        proxy_set_header X-Host $host;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Frontend "nginx";
    }
}

Using HTTP basic auth for EVA ICS authentication

The following example demonstrates how to use basic authentication and automatically log in user into SFA UI.

Firstly, set user_hook option in ./etc/sfa.ini, this will allow EVA ICS to sync htpasswd file with SFA users (make sure htpasswd program is installed as well).

[server]
.......
user_hook = /opt/eva/xbin/htpasswd.sh /opt/eva/etc/htpasswd

Then, front-end config (e.g. for NGINX) should look like:

upstream eva-sfa {
        server 127.0.0.1:8828;
    }

server {
    listen 80 default_server;

    location / {
        auth_basic $eva_authentication;
        auth_basic_user_file /opt/eva/etc/htpasswd;
        rewrite ^/pvt/(.+)$ /pvt?f=$1 last;
        proxy_buffers 16 16k;
        proxy_buffer_size 16k;
        proxy_busy_buffers_size 240k;
        proxy_pass http://eva-sfa;
        proxy_set_header X-Host $host;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto http;
        proxy_set_header X-Port $server_port;
        proxy_set_header X-Frontend "nginx";
    }

    location /ws {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
        proxy_pass http://eva-sfa;
        proxy_set_header X-Host $host;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto http;
        proxy_set_header X-Port $server_port;
        proxy_set_header X-Frontend "nginx";
    }
}

With such setup, EVA JS Framework-based interface doesn’t perform any authentication, $eva.start() function is called as soon as UI is loaded. API method login called by framework function will automatically log in user using basic authentication credentials provided to front-end server.