Logic Manager

EVA Logic Manager (LM PLC) - is a programmable logic controller.

This subsystem is designed to automatically manage hardware and decision-making process when the metrics are changed. Unlike standard PL controllers, LM PLC is a network-based controller, its mission is to control equipment in local networks and work as cloud controller via the Internet.

LM PLC operations can be event-based, cycle-based, and called manually by used.

LM PLC is customized and controlled via LM EI web interface or eva lm (lm-cmd) console application. It can also be integrated into other subsystems and third-party programs using LM API.

Additionally, you can use console applications for better control of the decision-making rules.

LM PLC additionally introduces one more control and monitoring item: logic variable (lvar). Logic variables are used to save and exchange system status data as well as function as flags and timers for organizing production cycles.

Any change in the status of units, sensors or logic variables is analyzed by the decision-making matrix of a certain LM controller. In case the rule conditions match, the controller calls the indicated macro that performs the specified actions.

Logic variables statuses are stored in the local database and can be accessed via LM API by other subsystems or third-party programs. Status changes are sent via notification system. To let LM PLC operate with the items of UCs in real time, it should be connected to MQTT server.

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

config/lm/main registry key

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

server:
  # system poll delay
  polldelay: 0.01
  # pid file
  pid-file: var/lm.pid
  # log file
  log-file: log/lm.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/lm.db
  # use registry to keep states
  #state-to-registry: true
  # 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/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
  # 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
  # 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
plc:
# set "false" to let LM PLC launch macros without thread pool
# (e.g. useful for handling rare bulk events), default is "true"
  use-core-pool: true
# cache state of remote items into local db (seconds ttl), off by default
  cache-remote-state: 0
#lurp:
# LURP replication
#  listen: 127.0.0.1:8911
#  buffer: 32768
#msad:
  # user authentication via MS Active Directory
  #host: ad.yourdomain.com
  #domain: yourdomain.com
  #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
upnp:
  # allow UPnP discovery of this controller
  listen: 0.0.0.0
  # discover controllers via UPnP on all interfaces, or list
  discover-on: all
sysapi:
  # enable remote file management functions
  file-management: true
  # allow entering setup mode
  setup-mode: true
  # allow rpvt
  rpvt: false
webapi:
  # web api listen on IP/port
  listen: 0.0.0.0:8817
  #ssl-listen: 0.0.0.0:8818
  #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
cloud:
  # default API key ID
  default-key: default
  # discover controllers as static
  #discover-as-static: true

Custom variables

All custom variables passed to logic control macros as-is.

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

Connecting UC controllers

Logic macros and decision-making matrix work only with the items known to the controller, so Logic Manager loads information about units and sensors from the connected Universal Controllers.

Prior to UC connection, it is necessary to connect LM PLC to MQTT server, where other controllers will send the events. Logic Manager reads the list of items and their initial status from the connected controllers; further status monitoring is performed via MQTT. In case MQTT server is inaccessible or has data exchange problems, states of the items are updated on every remote controller reload (reload_interval prop).

To connect UC controllers you should use eva lm console command or LM 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 lm controller append http://localhost:8812 -a secretkey -y

Configurations of connected controllers are stored in the following folder: runtime/lm_remote_uc.d/

Logic Manager automatically loads the connected controller data (its ID) and saves configuration to runtime/lm_remote_uc.d/ID.json file.

Items from remote controllers are loaded at the LM PLC start and then refreshed with reload_interval frequency set individually for each connected controller. If LM PLC 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 lm or LM API function list_remote:

eva lm remote -p unit
eva lm remote -p sensor

All connected controllers have the following properties that can be changed while LM PLC 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/)

Parameters are displayed with eva lm command or Logic Manager 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 can be either the controller ID only or the full ID in the following format: controller_type/ID (i.e. uc/controller1).

Macro execution queues

Prior to execution, the macros are put into global queue. The macros are executed progressively without waiting for the completion of the previous macro. The queue is used for reporting only and reserved for some internal functions. If a macro is required to block execution of the other ones, one should use lock and unlock macro functions operating similarly to SYS API locking.

The status of the macro in queue is similar to the status of the Universal Controller actions.

Startup and shutdown

To manage LM controller server, use:

  • eva lm server start start LM server
  • eva lm server stop stop LM server
  • eva lm server restart restart LM server
  • eva lm 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.