# Enapter Gateway 1.8.15

The Enapter Gateway is the energy site controller. It collects data from all energy devices connected via UCMs. The data is analysed and processed with user-defined commands from the Enapter Rule Engine.

Warning

Gateway 1.8.15 software works only with hardware provided by Enapter. To use Gateway Software 2.0 upgrade your hardware in accordance to technical requirements.

Note

The latest version available at https://fw.enapter.com (opens new window)

# Comparison With the Gateway 2.0

Gateway 2.0 Gateway 1.8.X
Hardware compatibility Can run on a wide range of Intel NUC computers in accordance to hardware requirements. Works only with hardware provided by Enapter.
Hardware requirements Intel NUC with Intel i5 or i7 CPU 10th / 11th generation. Intel NUC with Celeron CPU provided only by Enapter.
Operational Modes
Cloud and Island
Cloud
Virtual UCM support Virtual UCM supported No Virtual UCM supported
Rules Management Cloud web-based Interface Command Line Interface

# Change Log

# New Features

  • New mqtt bridge offline-mode setting allows to disable caching telemetry while gateway disconnected from Enapter Cloud
  • New rule-engine telemetry-store-interval setting allows to specify telemetry storage interval for Enapter Rule Engine (default 1800 seconds), settings this to lower value can improve performance

# Resources

Enapter Gateway 1.8.15 Quick Start Guide

# Installation Instructions

# Connect to the Gateway

To connect to the Gateway, open it's gateway page on https://cloud.enapter.com (opens new window) and press on Run Terminal button.

The secure connection will be established and terminal window will open inside your browser.

# To Verify Release and System Type

  1. Login as User Enapter with Password Enapter (default login ID).
  2. Run show version command, as in the following example.

Example 1-1 Displaying version information

[2fad8f] $ show version 
v1.8-rc8.8812 (cyclops)
[2fad8f] $

# Creating Bootable SD Card with Gateway Firmware

Note

If you are using Gateway Software 2.X.X please follow the Create Bootable USB Flash guide.

# Video Guide

# Requirements

To prepare your bootable card you will require:

  • 8 GB or bigger size SD card
  • SD card reader
  • Mac or PC with fast Internet connection

# Windows/Mac/Linux Update

  1. Download firmware image to your computer. The latest version of Gateway firmware you can find on https://fw.enapter.com (opens new window) website.

  2. Download and install Balena Etcher application which is used to write image to SD card from https://www.balena.io/etcher/ (opens new window) website.

  3. Start Etcher application

Application

  1. Select firmware file

  2. Lock switch located on the left side of the SD card. Make sure the Lock switch is slid up (unlock position). You will not be able to modify or delete the contents on the memory card if it is locked.

SD Card Unlock

  1. Plug the SD card into your card reader. At this step Etcher will automatically recognize your card. If you have several SD cards connected - don't forget to check you selected the right one.

Device

  1. Press Flash! button. Please note that at this step all data on your SD card will be destroyed. The flashing process will start - the app may require the administrator rights to proceed. The process will take some time and depends on speed of your card reader, card and computer.

Flashing

# Gateway Factory Reset

  1. Prepare SD card with latest firmware as described in Creating Bootable SD Card with Gateway Firmware.

  2. Prepare USB Flash Stick:

  • Format USB Flash Stick with FAT32 file system.

  • Create a txt file commands.txt at the USB Flash Stick.

  • Add command to commands.txt file and save it:

hard_reset = true
  1. Turn ON the Gateway.

  2. Wait for 1 minute while booting the system.

  3. Insert the USB Flash Stick into the Gateway.

  4. Wait for 15 seconds.

  5. Pull out the USB Flash Stick.

  6. Wait for 2 minutes while the Gateway rebooting.

  7. Check if Gateway Factory Reset was done properly: the txt file commands.txt on the USB Flash Stick should contain:

hard_reset = false
  1. Gateway Factory Reset is complete.

# User Interface Options

Two ways available for interfacing with the Enapter system: a command-line interface from web and from local Keyboard/Video/Mouse connection.

As both ways using CLI are mostly the same, all instructions in this guide applicable for both cases.

# The Command-Line Interface (CLI)

This section presents the following topics:

  • Command Modes
  • CLI Help
  • Command Completion

# Enapter Shell

The CLI of the Enapter system includes two families of commands:

  • Enapter-specific commands for operating and configuring the Enapter system.
  • Commands provided by the Linux operating system shell in which the Enapter CLI operates.

All users have access to operating system commands as well as Enapter shell commands.

# Command Modes

The are two command modes in Enapter CLI: operational mode and configuration mode.

  • Operational mode provides access to operational commands for showing help information, exiting CLI, run bash, etc.
  • Configuration provides access to commands for creating, modifying, deleting, committing and showing configuration information, as well as commands for navigating through the configuration hierarchy.

When you log on to the system, the system is in operational mode.

  • To enter configuration mode from operational mode, issue the configure command.
  • To return to operational mode from configuration mode, issue the exit command. If there are uncommitted configuration changes, you must either commit the changes using the commit command, or enter exit to discard the changes.

# Enter Configuration Mode

In configuration mode you can set, delete and show information. Enter configuration mode by typing configure at the command prompt in operational mode.

[d0a09d] $ configure
[d0a09d] conf $

[d0a09d] conf $ exit
[d0a09d] $

Notice how the command prompt changes to remind you what mode you are in.

# Command Completion

Pressing the <Tab> key provides command completion. You can use the <Tab> to show:

  • All available commands
  • All valid completions for a command partially typed in
  • The next available set of options for a command. You can use the <Tab> key iteratively in this way to discover complete command syntax.

Example 2-1 Use command completion on an unambiguous command

The following example requests command completion for the typed string sh. In this example, the command to be completed is unambiguous.

[d0a09d] conf $ sh <tab>
[d0a09d] conf $ show

# List of Possible Commands in Operational Mode

Command Description
exit Exit shell
help Display help message
services Services operations
show Show system information
bash Run Bash shell
configure Enter configuration mode
reboot Reboot server

# Public MQTT API

# Protocol V1

# Connection to MQTT

Public MQTT port is 9883.

# Device Telemetry API

# Device Telemetry

Provides Device telemetry.

Will be published every 1 second.

telemetry/v1/{id}
Payload Field Description
timestamp Message publishing timestamp
... Device-specific fields
# Example

Topic

telemetry/v1/A0B1

Payload

{
  "timestamp": 1514320289,
  "uptime": 2
}

# Key/Value Storage API

# Set

Sets variable value.

variables/v1/set/{variable-name}
Payload Field Description
variable-name Variable name
# Example

Topic

variables/v1/set/pid_target_pressure

Payload

{
  "value": "30"
}
# Get

Receive notification on variable's value changes.

variables/v1/get/{variable-name}
Payload Field Description
variable-name Variable name
# Example

Topic

variables/v1/get/pid_target_pressure

Payload

{
  "timestamp": 1602699378,
  "value": "32"
}

# Commands API

# Request Command Execution
commands/v1/{id}/requests
Payload Field Description
id Command execution ID, e.g. UUID
name Command name
arguments Optional, command arguments
expires Optional, command expiration timestamp
# Example

Topic

commands/v1/A0B1/requests

Payload

{
  "id": "ab3e364c-cab2-4cc1-872d-4d554530d587",
  "name": "impulse",
  "arguments": {
    "id": 1,
    "impulse": 300
  }
}
# Command Execution Responses
commands/v1/{id}/responses
Payload Field Description
id Required, command execution ID, e.g. UUID
state Required, command execution state, e.g. started
payload Optional, command state payload
# Example

Topic

commands/v1/A0B1/responses

Payload

{
  "id": "ab3e364c-cab2-4cc1-872d-4d554530d587",
  "name": "finished"
}

# Electrolyser EL 2.1

# Device Telemetry Payload

Field Description
timestamp Message publishing timestamp
status Electrolyser status string one of maintenance, expert, error, fatal, idle, steady, standby, curve, blowdown
is_running Indicates whether device is running boolean
has_errors Indicates whether any device errors boolean
has_warnings Indicates whether any device warnings boolean
errors List of electrolyser errors (opens new window)
warnings List of electrolyser warnings (opens new window)
electrolyte_level_very_high Indicates whether electrolyte level is higher than very high level
electrolyte_level_high Indicates whether electrolyte level is higher than high level
electrolyte_level_medium Indicates whether electrolyte level is higher than medium level
electrolyte_level_low Indicates whether electrolyte level is higher than low level
h2_flow H2 Production in Normal Liter/hour
h2_total Total H2 Produced in Normal Liter
stack_pressure H2 Stack Pressure in Bar
stack_voltage H2 Stack Voltage in Volt
stack_amperage H2 Stack Amperage in Ampere
outlet_pressure H2 Outlet Pressure in Bar
water_inlet_pressure Water Inlet Pressure in Bar
electrolyte_tank_temperature Electrolyte Tank Temperature in Celsius
electrolyte_downstream_temperature Downstream Temperature in Celsius
# Example
{
  "timestamp": 1514320289,
  "status": "steady",
  "is_running":  true,
  "has_errors":  true,
  "has_warnings": false,
  "h2_flow": 250.0,
  "h2_total": 10000,
  "stack_pressure": 30.1,
  "stack_voltage": 38.1,
  "stack_amperage": 12.3,
  "outlet_pressure":  30.0,
  "water_inlet_pressure": 1.2,
  "electrolyte_tank_temperature":  38.3,
  "electrolyte_downstream_temperature": 24.7,
  "errors": ["FP_01", "FP_03"],
  "warnings": [],
  "electrolyte_level_very_high": false,
  "electrolyte_level_high": false,
  "electrolyte_level_medium": true,
  "electrolyte_level_low": true
}

# Supported Commands

Command Name Description Arguments
start Start electrolyser
stop Stop electrolyser
reset Reset electrolyser
set_production_rate Set electrolyser production rate (in percents) value (float)
set_waterfill Force electrolyser to perform water refill operation value (boolean) (should be set to true)

# Dryer DRY 2.1

# Device Telemetry Payload

Field Description
timestamp Message publishing timestamp
status Dryer status string one of waiting_for_power, waiting_for_pressure, stopped_by_user, starting, standby, waiting_for_pressure, drying_0, cooling_0, switching_0, pressurizing_0, finalizing_0, drying_1, cooling_1, switching_1, pressurizing_1, finalizing_1, leak_input, leak_dryer, error
is_running Indicates whether device is running boolean
has_errors Indicates whether any device errors boolean
errors List of dryer errors (opens new window)
warnings List of dryer warnings (opens new window)
input_pressure H2 Inlet Pressure in Bar
output_pressure H2 Outlet Pressure in Bar
# Example
{
  "timestamp": 1547680704,
  "status": "drying_0",
  "is_running": true,
  "has_errors": true,
  "input_pressure": 30.5,
  "output_pressure": 26.1,
  "errors": ["TT00", "PT00"],
  "warings": []
}

# Supported Commands

Command Name Description
start Start dryer
stop Stop dryer
reset Reset dryer

# ENP-AI4

# Device Telemetry Payload

Field Description
timestamp Message publishing timestamp
ai1 Analog input 1 value, in volts
ai2 Analog input 2 value, in volts
ai3 Analog input 3 value, in volts
ai4 Analog input 4 value, in volts
# Example
{
    "timestamp":1608838307,
    "ai1":0.77716428041458,
    "ai2":0.038626454770565,
    "ai3":0.004635174293071,
    "ai4":0.046351749449968
}

# ENP-RL6

# Device Telemetry Payload

Field Description
timestamp Message publishing timestamp
r1 Channel 1 state boolean
r2 Channel 2 state boolean
r3 Channel 3 state boolean
r4 Channel 4 state boolean
r5 Channel 5 state boolean
r6 Channel 6 state boolean
# Example
{
  "timestamp":1608838306,
  "r1":false,
  "r2":false,
  "r3":false,
  "r4":false,
  "r5":false,
  "r6":false
}

# Supported Commands

Command Name Description Arguments
open Open single channel id
close Close single channel id
impulse Send impulse to channel id, time
open_all Open all channels
close_all Open all channels

# Examples

# Configuration

Before starting integration process Public MQTT API should be configured. See User Interface Options chapter of Gateway Programming Guide.

To do this - enter configuration mode on gateway shell and set basic parameters.

# Setup MQTT Port and Authentication

Public MQTT port is 9883.

set mqtt public authentication username "public"
set mqtt public authentication password "password"
commit
save

Resulting configuration tree will be:

{
    mqtt {
        public {
            authentication {
                username "public"
                passsword ********
            }
        }
    }
}

# Configure Custom Telemetry Sending Interval
set mqtt public telemetry-interval 5
commit
save

Resulting configuration tree will be:

{
    mqtt {
        public {
            telemetry-interval 5
        }
    }
}
# Enable Public API for Devices
set mqtt public devices enapter-electrolyser-v21 <EL_1_DEVICE_ID> enabled true
set mqtt public devices enapter-electrolyser-v21 <EL_2_DEVICE_ID> enabled true
set mqtt public devices enapter-dryer <DRYER_DEVICE_ID> enabled true
commit
save

Resulting configuration tree will be:

{
    mqtt {
        public {
            devices {
                enapter-electrolyser-v21 8BF3C483286E348B0045E9F15EBCB67EFC268B4A {
                    enabled true
                }
                enapter-electrolyser-v21 A9CCB145472FF183535E93427D007B6844E369BB {
                    enabled true
                }
                enapter-dryer 2B2E42A378DB505BDBD0A9F41F2D4603D30A51E5 {
                    enabled true
                }
            }
        }
    }
}

# Define variables
set variables variable <VARIABLE_NAME> type float
commit
save

Resulting configuration tree will be:

{
    variables {
        variable target-pid-pressure {
            type float
        }
    }
}

# Receiving Device Telemetry
  1. Connect to mqtt on gateway ip address, specified port, with specified username & password,
  2. Subscribe to telemetry topic
mosquitto_sub -d -v -p 9883 -h 192.168.1.1 -u public -P password -t "telemetry/v1/<DEVICE_ID>"
# Set Variable Value
  1. Connect to mqtt on gateway ip address, specified port, with specified username & password,
  2. Publish message to set variable topic
mosquitto_pub -p 9883 -h 192.168.1.1 -u public -P password -t "variables/v1/set/<FLOAT_VARIABLE_NAME>" -m "{ \"value\": 30.5 }"
mosquitto_pub -p 9883 -h 192.168.1.1 -u public -P password -t "variables/v1/set/<BOOL_VARIABLE_NAME>" -m "{ \"value\": false }"
# Command Variables

Variables can be used to execute commands.

For example electrolysers can be started when start-els variable set to true.

  1. Define variable
set variables variable start-els type bool
commit
save
  1. Activate ELs plugin
set rule-engine plugin electrolyser-v21 enabled true
commit
save
exit
  1. Configure devices in rule engine
set rule-engine devices electrolyser-v21 <EL_1_DEVICE_ID> enabled true
set rule-engine devices electrolyser-v21 <EL_2_DEVICE_ID> enabled true
  1. Add rule to activate ELs when variable set to true
set rule-engine rule 1-start-els condition 1 variable start-els compare-operator eq
set rule-engine rule 1-start-els condition 1 variable start-els value "true"
set rule-engine rule 1-start-els action 1 start-electrolyser-v21 device <EL_1_DEVICE_ID>
set rule-engine rule 1-start-els action 2 start-electrolyser-v21 device <EL_2_DEVICE_ID>
set rule-engine rule 1-start-els action 3 set-variable start-els value "false"

Resulting configuration tree will be:

{
    variables {
        variable start-els {
            type bool
        }
    }
    rule-engine {
        rule 1-start-els {
            condition 1 {
                variable run-all-els {
                    compare-operator eq
                    value "true"
                }
            }
            action 1 {
                start-electrolyser-v21 {
                    device 8BF3C483286E348B0045E9F15EBCB67EFC268B4A
                }
            }
            action 2 {
                start-electrolyser-v21 {
                    device A9CCB145472FF183535E93427D007B6844E369BB
                }
            }
            action 3 {
                set-variable start-els {
                    value "false"
                }
            }
        }
    }
}
# Using Variable Value in Condition

For example electrolysers can be stopped once system reaches target pressure.

  1. Define variable
set variables variable target-pressure type float
commit
save
  1. Activate ELs and dryers plugins
set rule-engine plugin electrolyser-v21 enabled true
set rule-engine plugin dryer enabled true
commit
save
exit
  1. Configure devices in rule engine
set rule-engine devices electrolyser-v21 <EL_DEVICE_ID> enabled true
set rule-engine devices dryer <DRYER_DEVICE_ID> enabled true
  1. Add rule to stop EL when system's target pressure reaches value defined in target-pressure variable
set rule-engine rule 1-stop-el condition 1-dryer-pressure dryer <DRYER_DEVICE_ID> if "device.output_pressure_avg(60) > var(\"target-pressure\")"
set rule-engine rule 1-stop-el action 1 stop-electrolyser-v21 device <EL_DEVICE_ID>

Resulting configuration tree will be:

{
    variables {
        variable target-pressure {
            type float
        }
    }
    rule-engine {
        rule 1-stop-el {
            condition 1-dryer-pressure {
                dryer 2B2E42A378DB505BDBD0A9F41F2D4603D30A51E5 {
                    if "device.output_pressure_avg(60) > var(\"target-pressure\")"
                }
            }
            action 1 {
                stop-electrolyser-v21 {
                    device 8BF3C483286E348B0045E9F15EBCB67EFC268B4A
                }
            }
        }
    }
}

# Rule Engine Administration Guide

Enapter Rule Engine should be used as a convenience feature for basic non-realtime automation and not for life-sustaining or safety-critical use cases. Rules depend on working internet, Wi-Fi, and Enapter Cloud. Enapter is not responsible for any harms or losses incurred as a result of any failed automation.

# Enapter Dryer Plugin

# Activation Plugin

[d0a09d] $ configure
[d0a09d] conf # set rule-engine plugin dryer enabled true
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit

# Available Actions

Action Description
start-dryer Start dryer command
stop-dryer Stop dryer command
reboot-dryer Reboot dryer command

# Expressions Available in Conditions

Expression Description Values
online Device online status boolean
has_errors Indicates whether any device errors boolean
errors.value Dryer errors list table
state.value Dryer state one of waiting_for_power, waiting_for_pressure, stopped_by_user, starting, drying_0, cooling_0, switching_0, pressurizing_0, finalizing_0, drying_1, cooling_1, switching_1, pressurizing_1, finalizing_1, leak_input, leak_dryer, error
state.seconds_in_state Number of seconds in current state integer
input_pressure Input pressure (bar) float
input_pressure_avg(10) Input pressure (bar) 10 seconds average float
output_pressure Output pressure (bar) float
output_pressure_avg(10) Output pressure (bar) 10 seconds average float
device:is_running() Whether dryer currently running or not boolean
# Example
[d0a09d] conf # set rule-engine rule 10 condition 10 dryer <DRYER_DEVICE_ID> if "not device:is_running() and output_pressure_avg(120) < 30"

# Enapter Electrolyser Plugin

# Activation Plugin

[d0a09d] $ configure
[d0a09d] conf # set rule-engine plugin electrolyser enabled true
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit

# Available Actions

Action Description
start-electrolyser Start electrolyser command
stop-electrolyser Stop electrolyser command
start-electrolyser-group Start electrolysers group command
stop-electrolyser-group Stop electrolysers group command

# Expressions Available in Conditions

Expression Description Values
online Device online status boolean
state.value Electrolyser state one of none, power_on, wait_start_comm, wait_power_cond, restart_with_max_press, delay_dc_dc, hydration, ramp_up, steady, ramp_down, purge, heating, error, warning
state.seconds_in_state Number of seconds in current state integer
stack_amp Electrolyser stack amperage float
stack_amp_avg(10) Electrolyser stack amperage 10 seconds average float
stack_volt Electrolyser stack voltage float
stack_volt_avg(10) Electrolyser stack voltage 10 seconds average float
device:is_running() Whether electrolyser currently running or not boolean
# Example
[d0a09d] conf # set rule-engine rule 10 condition 10 electrolyser <EL_DEVICE_ID> if "online and device:is_running() and state.value == 'steady' or stack_amp_avg(45) > 12.5"

# Enapter Electrolyser EL 2.1 Plugin

# Activation Plugin

[d0a09d] $ configure
[d0a09d] conf # set rule-engine plugin electrolyser-v21 enabled true
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit

# Available Actions

Action Description
start-electrolyser-v21 Start electrolyser command
stop-electrolyser-v21 Stop electrolyser command
reset-electrolyser-v21 Reset electrolyser command

# Expressions Available in Conditions

Expression Description Values
online Device online status boolean
has_errors Indicates whether any device errors boolean
has_warnings Indicates whether any device warnings boolean
errors.value Electrolyser errors list table
warnings.value Electrolyser warnings list table
state.value Electrolyser state one of maintenance, expert, error, fatal, idle, steady, standby, curve, blowdown
state.seconds_in_state Number of seconds in current state integer
stack_state.value Electrolyser stack state one of none, maintenance, idle, warmingup, hydration, rampup1, rampup2, steady, purge, rampdown1, rampdown2, rampdown3, curve, maxpressure, halt
stack_state.seconds_in_state Number of seconds in current stack state integer
h2_flow Electrolyser current H2 production float
h2_flow_avg(10) Electrolyser current H2 production 10 seconds average float
outlet_pressure Outer Hydrogen Pressure float
outlet_pressure_avg(10) Outer Hydrogen Pressure 10 seconds average float
inlet_pressure Inlet Hydrogen Pressure float
inlet_pressure_avg(10) Inlet Hydrogen Pressure 10 seconds average float
water_inlet_pressure Water Inlet Pressure float
water_inlet_pressure_avg(10) Water Inlet Pressure 10 seconds average float
electrolyte_temperature Electrolyte Temperature float
electrolyte_temperature_avg(10) Electrolyte Temperature 10 seconds average float
stack_current Stack Current float
stack_current_avg(10) Stack Current 10 seconds average float
device:is_running() Whether electrolyser currently running or not boolean
# Example
[d0a09d] conf # set rule-engine rule 10 condition 10 electrolyser-v21 <EL_DEVICE_ID> if "online and device:is_running() and state.value == 'steady' or stack_amp_avg(45) > 12.5"

# EL 2.1 Heartbeat

set el21-heartbeat device <device_id> command added to the Electrolyser will activate Safety Heartbeat. If the Electrolyser does not receive the heartbeat in a time (heartbeat period) — the machine will normally shut down.

Adding notify-offline command will add the check of connection to Cloud.

  • notify-offline false - Heartbeat will be sent even Gateway is disconnected from Cloud

  • notify-offline true - if no connection between gateway and cloud - Heartbeat will not be sent

  • period - period of checks, in seconds

# Example
set el21-heartbeat device <EL21_DEVICE_ID>
set el21-heartbeat notify-offline true
set el21-heartbeat period 30

# Enapter Electrolyser EL 2.1 Smart Production Rate Control

Electrolyser EL 2.1 Smart Production Rate Control enables control of the group of the EL 2.1 electrolysers as if it is one big electrolyser. The plugin automatically selects the strategy for start and stop of the electrolyser and production control in the allowed ranges.

# Activation Plugin

[d0a09d] $ configure
[d0a09d] conf # set rule-engine plugin electrolyser-v21-smart-production-control enabled true
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit

# Example

Enable plugin

[d0a09d] $ configure
[d0a09d] conf # set rule-engine plugin electrolyser-v21-smart-production-control enabled true
[d0a09d] conf # set rule-engine plugin electrolyser-v21 enabled true
[d0a09d] conf # commit
[d0a09d] conf # exit

Configure Public MQTT interface

[d0a09d] $ configure
[d0a09d] conf # set mqtt public authentication username public
[d0a09d] conf # set mqtt public authentication password public
[d0a09d] conf # set variables variable els-target-production type float

Enable EL 2.1 electrolysers management and aggregate them into one group

[d0a09d] conf # set rule-engine devices electrolyser-v21 HWID1 enabled true
[d0a09d] conf # set rule-engine devices electrolyser-v21 HWID2 enabled true
[d0a09d] conf # set rule-engine devices electrolyser-v21 HWID3 enabled true

[d0a09d] conf # set rule-engine groups electrolyser-v21 ELS device HWID1
[d0a09d] conf # set rule-engine groups electrolyser-v21 ELS device HWID2
[d0a09d] conf # set rule-engine groups electrolyser-v21 ELS device HWID3

Configure plugin to control group of electrolysers ELS with variable els-target-production

[d0a09d] conf # set rule-engine electrolyser-v21-smart-production-control SMART1 electrolysers-group ELS
[d0a09d] conf # set rule-engine electrolyser-v21-smart-production-control SMART1 target-production-variable-name els-target-production

Save and apply configuration

[d0a09d] conf # save
[d0a09d] conf # commit

To change variable setpoint from command interface to 1000 NL/h use the following command in configuration mode

[d0a09d] conf # run variables set els-target-production value 1000

It is also possible to access this variable through Public MQTT interface.

# Enapter Tank Module Plugin

# Activation Plugin

[d0a09d] $ configure
[d0a09d] conf # set rule-engine plugin tank enabled true
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit

# Expressions Available in Conditions

Expression Description Values
online Device online status boolean
pressure1 Pressure input #1 value float
pressure1_avg(10) Pressure input #1 10 seconds average float
pressure2 Pressure input #2 value float
pressure2_avg(10) Pressure input #2 10 seconds average float
temp1 Temperature input #1 value float
temp1_avg(10) Temperature input #1 10 seconds average float
temp2 Temperature input #2 value float
temp2_avg(10) Temperature input #2 10 seconds average float
# Example
[d0a09d] conf # set rule-engine rule 10 condition 10 tank TNK1 if "pressure1_avg(120) < 30"

# Gas Sensor Plugin

# Activation Plugin

[d0a09d] $ configure
[d0a09d] conf # set rule-engine plugin gas-sensor enabled true
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit

# Expressions Available in Conditions

Expression Description Values
online Device online status boolean
ai1 Analog input #1 value float
ai1_avg(10) Analog input #1 value 10 seconds average float
ai1_avg_with_offset(10, 60) Analog input #1 value 10 seconds average with 60 seconds offset float
ai2 Analog input #2 value float
ai2_avg(10) Analog input #2 value 10 seconds average float
ai2_avg_with_offset(10, 60) Analog input #2 value 10 seconds average with 60 seconds offset float
ai3 Analog input #3 value float
ai3_avg(10) Analog input #3 value 10 seconds average float
ai3_avg_with_offset(10, 60) Analog input #3 value 10 seconds average with 60 seconds offset float
ai4 Analog input #4 value float
ai4_avg(10) Analog input #4 value 10 seconds average float
ai4_avg_with_offset(10, 60) Analog input #4 value 10 seconds average with 60 seconds offset float

# Enapter RL6 Module Plugin

# Activation Plugin

[d0a09d] $ configure
[d0a09d] conf # set rule-engine plugin enp-rl6 enabled true
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit

# Expressions Available in Conditions

Expression Description Values
online Device online status boolean
r1 Relay channel #1 state boolean
r2 Relay channel #2 state boolean
r3 Relay channel #3 state boolean
r4 Relay channel #4 state boolean
r5 Relay channel #5 state boolean
r6 Relay channel #6 state boolean

# Available Actions

Action Description
enp-rl6-open Open relay channel
enp-rl6-close Close relay channel
enp-rl6-impulse Send impulse to relay channel
enp-rl6-open-all Open all channels
enp-rl6-close-all Close all channels
# Example
[d0a09d] conf # set rule-engine rule 10 condition 10 enp-rl6 <RL6_DEVICE_ID> if "r1"

# Lua Conditions

Lua conditions can be used for programming complex logic dependent of several devices.

For more convenient work on complex scripts Enapter shell support editing values in Vim (default) or Nano editor. To set preferable editor use following command:

[d0a09d] conf # set shell editor nano

or

[d0a09d] conf # set shell editor vi

To edit value use edit command in configuration mode:

[d0a09d] conf # edit rule-engine rule 10-test condition 10 lua

To exit from Vim editor use :wq<Enter>

Lua condition code block expected to return boolean value.

The most simple Lua condition will be:

return true

# Multiple Electrolysers and Single Dryer Management Example for EL 2.0 and DRY

[d0a09d] $ conf
[d0a09d] conf # set shell editor nano
[d0a09d] conf # set rule-engine plugin electrolyser enabled true
[d0a09d] conf # set rule-engine plugin dryer enabled true
[d0a09d] conf # set rule-engine plugin dryer-management-rule enabled "true"
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit
[d0a09d] $ conf
[d0a09d] conf # set rule-engine devices electrolyser <EL_1_DEVICE_ID> enabled true
[d0a09d] conf # set rule-engine devices electrolyser <EL_1_DEVICE_ID> power 2400
[d0a09d] conf # set rule-engine devices electrolyser <EL_2_DEVICE_ID> enabled true
[d0a09d] conf # set rule-engine devices electrolyser <EL_2_DEVICE_ID> power 2400
[d0a09d] conf # set rule-engine devices dryer <DRYER_DEVICE_ID> enabled "true"
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-management dryer <DRYER_DEVICE_ID>
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-management electrolyser <EL_1_DEVICE_ID>
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-management electrolyser <EL_2_DEVICE_ID>

# Multiple Electrolysers and Single Dryer with PID Regulation Example for EL2.1 and DRY

This is example for managing production with pressure set point at 30 bar and minimal production rate at 60%.

[d0a09d] $ conf
[d0a09d] conf # set shell editor nano
[d0a09d] conf # set rule-engine plugin dryer enabled "true"
[d0a09d] conf # set rule-engine plugin electrolyser-v21 enabled "true"
[d0a09d] conf # set rule-engine plugin electrolyser-v21-dryer-output-based-production-pid enabled "true"
[d0a09d] conf # set rule-engine plugin dryer-management-rule enabled "true"
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit
[d0a09d] $ conf
[d0a09d] conf # set rule-engine devices dryer <DRYER_DEVICE_ID> enabled "true"
[d0a09d] conf # set rule-engine devices electrolyser-v21 <EL_1_DEVICE_ID> enabled "true"
[d0a09d] conf # set rule-engine devices electrolyser-v21 <EL_1_DEVICE_ID> power "2400"
[d0a09d] conf # set rule-engine devices electrolyser-v21 <EL_2_DEVICE_ID> enabled "true"
[d0a09d] conf # set rule-engine devices electrolyser-v21 <EL_2_DEVICE_ID> power "2400"
[d0a09d] conf # set rule-engine plugin electrolyser-v21-dryer-output-based-production-pid enabled "true"
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-mgmt dryer <DRYER_DEVICE_ID>
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-mgmt electrolyser <EL_1_DEVICE_ID>
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-mgmt electrolyser <EL_2_DEVICE_ID>
[d0a09d] conf # set rule-engine electrolyser-v21-dryer-output-based-production-pid 500-pid d "1"
[d0a09d] conf # set rule-engine electrolyser-v21-dryer-output-based-production-pid 500-pid dryers-group "PID-DRYER"
[d0a09d] conf # set rule-engine electrolyser-v21-dryer-output-based-production-pid 500-pid electrolysers-group "PID-ELS"
[d0a09d] conf # set rule-engine electrolyser-v21-dryer-output-based-production-pid 500-pid i "0.001"
[d0a09d] conf # set rule-engine electrolyser-v21-dryer-output-based-production-pid 500-pid min "60"
[d0a09d] conf # set rule-engine electrolyser-v21-dryer-output-based-production-pid 500-pid p "2"
[d0a09d] conf # set rule-engine electrolyser-v21-dryer-output-based-production-pid 500-pid target-pressure "30"
[d0a09d] conf # set rule-engine groups dryer PID-DRYER device <DRYER_DEVICE_ID>
[d0a09d] conf # set rule-engine groups electrolyser-v21 PID-ELS device <EL_1_DEVICE_ID>
[d0a09d] conf # set rule-engine groups electrolyser-v21 PID-ELS device <EL_2_DEVICE_ID>

# 6 Steps for Time-based Electrolyser Start / Stop Using LUA

This example uses os.date (opens new window) function. EL 2.1 device id 123 is dummy and for real use case you should use device available in rule engine. Please note that rule engine operates with GMT.

  1. Enter configuration mode:
[bd0745] $ configure
[bd0745] conf #
  1. Enable plugin:
[bd0745] conf # set rule-engine plugin electrolyser-v21 enabled true
[bd0745] conf #
  1. Save configuration and restart configuration
[bd0745] conf # commit
[bd0745] conf # save
[bd0745] conf # exit
[bd0745] $ configure
[bd0745] conf #
  1. Enable Electrolyser with ID 123 (use TAB for autocompletion)
[bd0745] conf # set rule-engine devices electrolyser-v21 123 enabled true
[bd0745] conf # set rule-engine devices electrolyser-v21 123 power 2400
[bd0745] conf # set rule-engine devices electrolyser-v21 123 cooldown-period 60
[bd0745] conf #
  1. Set the time based control rule. Start EL 2.1 ID 123 at 15:05 GMT.
[bd0745] conf # set rule-engine rule 10 action 1 start-electrolyser-v21 device 123
[bd0745] conf # set rule-engine rule 10 condition 1 lua "return os.date('%H:%M') == '15:05'"
[bd0745] conf #
  1. Set the time based control rule. Stop EL 2.1 ID 123 at 16:05 GMT.
[bd0745] conf # set rule-engine rule 20 action 1 stop-electrolyser-v21 device 123
[bd0745] conf # set rule-engine rule 20 condition 1 lua "return os.date('%H:%M') == '16:05'"
[bd0745] conf #

# Configuration

This chapter introduces you to basic configuration concepts, and then walks you through one configuration scenario:

  • Basic system configuration tasks

This chapter presents the following topics:

  • Configuration Basics
  • Scenario: Basic System Configuration

# Configuration Basics

This section presents the following topics

  • Configuration Hierarchy
  • Adding and Modifying Configuration
  • Deleting Configuration
  • Committing Configuration Changes
  • Discarding Configuration Changes
  • Saving Configuration

# Configuration Hierarchy

From the system point of view, a configuration node is different from a simple configuration attribute statement. A configuration attribute statement takes the form of attribute value, as in the following example.

rule 1 action test

A configuration node always has an enclosing pair of braces:

rule 2 {
    description test
}

# Adding and Modifying Configuration

Add new configuration by creating a configuration node, using the set command in configuration mode. Modify existing configuration also by using the set command in configuration mode.

Example 3-1 Add configuration

[d0a09d] conf $ set rule-engine rule 1 action test start-electrolyser device <EL_DEVICE_ID>
[d0a09d] conf $

Now use diff command to see the addition.

[d0a09d] conf $ diff
  rule-engine {
    devices {
      electrolyser 8BF3C483286E348B0045E9F15EBCB67EFC268B4A {
        enabled true
      }
    }
+   rule 1 {
+     description test
    }
  }

Note the “+” in front of the new statement. This shows that this statement has been added to the configuration but the change is not yet committed. The change does not take effect until configuration is committed using the commit command.

# Modifying Configuration

For the most part, modifying configuration is the same as adding configuration by using the set command. This works for identifiers of nodes containing a single instance.

# Deleting Configuration

You can delete configuration statements or complete configuration nodes using the delete command.

[d0a09d] conf $ delete rule-engine rule 2
[d0a09d] conf $ diff
-   rule 2 {
-     description test
-   }

Note that the deleted parts of configuration have - in front of the statement.

# Run Command

You can execute operational mode commands from configuration mode using run command.

[d0a09d] conf $ run show configuration commands
set rule-engine devices electrolyser <EL_DEVICE_ID> enabled "true"
set rule-engine devices electrolyser <EL_DEVICE_ID> power "2400"

Note that you can also use bash commands with run command.

# Discard All Uncommitted Changes

To discard all uncommitted changes use discard command. It is faster than delete all changes you don't want to have.

Note that show command or diff command won't display any - or + as diff compares current configuration with committed one.

# Saving Configuration

To prevent your configuration from deleting with reboot, you need to save it.

[d0a09d] conf $ save
[d0a09d] conf $

# List of Current Operational Mode Commands

Command Description
run Run an operational-mode command
exit Exit configuration mode
commit Commit the current set of changes
discard Discard uncommitted changes
edit Edit node value in editor
cd Step into node
rollback Rollback to a prior config revision
save Save current configuration
diff Show state diff
show Show state value
set Set value
delete Delete value

# Scenario of Basic System Configuration

This chapter goes through initial system configuration tasks using the CLI. These tasks are required for almost any scenario in which you might use Enapter's shell. These include the following:

  • Overview
  • Logging on
  • Checking system logs
  • Activating rule engine plugins
  • Configuring devices (EL, Dryer, Inverters, etc.)
  • Setting devices groups
  • Setting standard rules actions and conditions
  • Examples

# Logging On

The first step is to log on using web management console.

Example 4-1 Log in and entering configuration mode.


Possible completions:
   exit         Exit shell
   help         Display help message
 > services     Services operations
 > show         Show system information
   bash         Run Bash shell
   configure    Enter configuration mode
   reboot       Reboot server

[d0a09d] $

In configuration mode you can set, delete and show information. Enter configuration mode by typing configure at the command prompt in operational mode.

[d0a09d] $ configure
[d0a09d] conf $

[d0a09d] conf $ exit
[d0a09d] $

You can use completion with <TAB> key at any moment to check available commands.

# Checking System Logs

Looking into logs helps you to understand what is happening with the system. To do this you need to open operational mode and type command show logs.

Example 4-2 Show logs

[d0a09d] $ show logs
2019-09-29T12:25:40Z [I] mosquitto             1569759940: Saving in-memory database to /user/var/lib/mosquitto/data/mosquitto.db.
2019-09-29T12:26:41Z [I] mosquitto             1569760001: Saving in-memory database to /user/var/lib/mosquitto/data/mosquitto.db.
2019-09-29T12:27:10Z [N] gateway-controller    Property Discoverable modify to 1

# Activating Rule Engine Plugins

You can activate Rule Engine Plugins by running the set rule-engine plugin <plugin_name> enabled true command:

[d0a09d] conf # set rule-engine plugin electrolyser enabled true
[d0a09d] conf # set rule-engine plugin dryer enabled true

List of supported plugins:

Plugin Name Description
electrolyser Enapter Electrolyser EL 2.0 / EL500 / ELS 1000 device support
electrolyser-v21 Enapter Electrolyser EL 2.1 support
dryer Enapter dryer device support
dryer-management-rule Enapter dryer management rule
changeover-switch Relay switch module device support
power-meter Power meter module device support
tank Enapter Tank module device support
enp-ai4 Enapter ENP-AI4 UCM support
enp-rl6 Enapter ENP-RL6 UCM support
gas-sensor Hydrogen sensor support
electrolyser-v21-el-output-based-production-pid Enapter EL 2.1 PID control based on production rate
electrolyser-v21-dryer-output-based-production-pid Enapter EL 2.1 PID control based on dryer output pressure

To apply changes and activate selected plugins please commit and save changes, exit configuration mode and re-enter configuration mode with conf command.

# Configuring Devices

To add devices you need set command. It allows Rule Engine to use rules to automatically control a device.

[d0a09d] conf # set rule-engine devices electrolyser <EL_DEVICE_ID> enabled true
[d0a09d] conf # set rule-engine devices electrolyser <EL_DEVICE_ID> power 2400
[d0a09d] conf # set rule-engine devices dryer <DRYER_DEVICE_ID> enabled true

# Setting Devices Groups

[d0a09d] conf # set rule-engine groups electrolyser ELS device <EL_DEVICE_ID> 

# Setting Standard Rules Actions and Conditions

You can configure custom rules by:

[d0a09d] conf # set rule-engine rule 10-dryer-rule action 10 start-dryer device <DRYER_DEVICE_ID>

You can do many things with rules.

Action Description
lua Evaluate custom LUA script
start-dryer Start dryer
stop-dryer Stop dryer
start-electrolyser Start electrolyser
stop-electrolyser Stop electrolyser
start-electrolyser-group Start electrolysers group
stop-electrolyser-group Stop electrolysers group

For writing new rule you need to set action (as described above), condition and description (optional).

Condition

[d0a09d] conf # set rule-engine rule 10-dryer-rule condition 10 electrolyser <EL_DEVICE_ID> if "device:is_running()"

Possible conditions:

Conditions Description
description Description
disable Disable
time Time condition
lua LUA script
battery SMA Battery Inverter condition
changeover-switch Relay switch status condition
dryer Enapter dryer condition
electrolyser Enapter Electrolyser condition
irradiance-sensor Irradiance Sensor condition
power-meter Power meter module condition
tank Enapter tank module condition

Now you can look into your rule engine configuration by running show rule-engine command.

plugin dryer {
  enabled true
}
plugin electrolyser {
  enabled true
}
devices {
  electrolyser BE24AADBEB35CB53814620E1CA98D6A4F9DBC72F {
    enabled true
    power 2400
  }
  dryer EB7AD544D0F4BC2BEDE7BA0C7EC2EBE048239035 {
    enabled true
  }
}
groups {
  electrolyser ELS {
    device BE24AADBEB35CB53814620E1CA98D6A4F9DBC72F
  }
}
rule 10-dryer-rule {
  action 10 {
    start-dryer {
      device EB7AD544D0F4BC2BEDE7BA0C7EC2EBE048239035
    }
  }
  condition 10 {
    electrolyser BE24AADBEB35CB53814620E1CA98D6A4F9DBC72F {
      if device:is_running()
    }
  }
}

# Examples

# Rules for Automatic Dryer Start/Stop
[d0a09d] $ conf
[d0a09d] conf # set rule-engine plugin electrolyser enabled true
[d0a09d] conf # set rule-engine plugin dryer enabled true
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit
[d0a09d] $ conf
[d0a09d] conf # set rule-engine devices electrolyser <EL_DEVICE_ID> enabled true
[d0a09d] conf # set rule-engine devices electrolyser <EL_DEVICE_ID> power 2400
[d0a09d] conf # set rule-engine devices dryer <DRYER_DEVICE_ID> enabled true
[d0a09d] conf # set rule-engine rule 10-start-dryer-rule action 10 start-dryer device <DRYER_DEVICE_ID>
[d0a09d] conf # set rule-engine rule 10-start-dryer-rule condition 10 electrolyser <EL_DEVICE_ID> if "device:is_running()"
[d0a09d] conf # set rule-engine rule 20-stop-dryer-rule action 10 stop-dryer device <DRYER_DEVICE_ID>
[d0a09d] conf # set rule-engine rule 20-stop-dryer-rule condition 10 electrolyser <EL_DEVICE_ID> if "not device:is_running()"
[d0a09d] conf # save 
[d0a09d] conf # commit
[d0a09d] conf # show rule-engine
devices {
  dryer EB7AD544D0F4BC2BEDE7BA0C7EC2EBE048239035 {
    enabled true
  }
  electrolyser BE24AADBEB35CB53814620E1CA98D6A4F9DBC72F {
    enabled true
    power 2400
  }
}
plugin dryer {
  enabled true
}
plugin electrolyser {
  enabled true
}
rule 10-start-dryer-rule {
  action 10 {
    start-dryer {
      device EB7AD544D0F4BC2BEDE7BA0C7EC2EBE048239035
    }
  }
  condition 10 {
    electrolyser BE24AADBEB35CB53814620E1CA98D6A4F9DBC72F {
      if device:is_running()
    }
  }
}
rule 20-stop-dryer-rule {
  action 10 {
    stop-dryer {
      device EB7AD544D0F4BC2BEDE7BA0C7EC2EBE048239035
    }
  }
  condition 10 {
    electrolyser BE24AADBEB35CB53814620E1CA98D6A4F9DBC72F {
      if "not device:is_running()"
    }
  }
}

# Checking Rule Engine Logs

[d0a09d] # show logs service gateway-rule-engine
2020-03-31T17:03:29Z [I] gateway-rule-engine   Rule 1/2 (10-start-dryer-rule):
2020-03-31T17:03:29Z [I] gateway-rule-engine    Condition result: false
2020-03-31T17:03:29Z [I] gateway-rule-engine    Condition execution log: 
2020-03-31T17:03:29Z [I] gateway-rule-engine            [INFO] Device offline, exiting condition with `false` result

# Known Bugs

  • Experiencing issues with receiving logs in Enapter Cloud. Please don't use system -> send-syslog-logs-to-enapter option for a now.

  • Blueprinted device actions (commands) doesn't work in Rule Engine. In general, the stable version of Gateway doesn't support Blueprints therefore it is not recommend to use it together with Blueprints.

  • After firmware update configuration migration might be needed. In case the following message is shown:

    [a6b84e] conf # show
    Unhandled error happened: GatewayShellApi::ConfigurationTree::ReferenceTreeMismatchError
    Stacktrace: ["/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/configuration_tree.rb:124:in `match_to_reference_tree'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/configuration_tree.rb:27:in `curly_tree_view'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/shell.rb:143:in `block in tree_view'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/shell.rb:139:in `map'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/shell.rb:139:in `tree_view'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/shell.rb:348:in `show_path'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/shell.rb:170:in `process_line'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/shell.rb:95:in `block in run!'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/shell.rb:86:in `loop'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/shell.rb:86:in `run!'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/lib/gateway_shell/shell.rb:35:in `run!'", "/usr/lib/ruby/gems/2.7.0/gems/gateway-shell-0.0.1/bin/gateway-shell:32:in `<top (required)>'", "/usr/bin/gateway-shell:23:in `load'", "/usr/bin/gateway-shell:23:in `<main>'"]
    [a6b84e] conf
    

    Following fix must be applied.

    Switch to superuser mode:

    [bd0745] $ bash
    enapter@gateway:~$ sudo su -
    # KEEP LOGS FOR ALL CHANGES ALL THE TIME IN /user/maintenance-log
    # USE log <text> COMMAND TO ADD UPDATE
    # USE shlog COMMAND TO VIEW LOG
    # LATEST CHANGES ARE ON THE BOTTOM
    
    root@gateway:~$
    

    Create the migration file

    # in bash shell with root access
    cat <<-EOF > /user/migrate-shell-state
    #!/usr/bin/ruby
    require 'gateway_shell_api'
    client = GatewayShellApi::Client.new(host: '127.0.0.1', port: 9874)
    client.delete(['ntp'], '') rescue nil
    client.delete(['ota'], '') rescue nil
    client.save
    EOF
    

    Make migration script executable and run it

    root@gateway:~$ chmod +x /user/migrate-shell-state
    root@gateway:~$ /user/migrate-shell-state
    root@gateway:~$