# 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 | ||
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
- Login as User
Enapter
with PasswordEnapter
(default login ID). - 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
Download firmware image to your computer. The latest version of Gateway firmware you can find on https://fw.enapter.com (opens new window) website.
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.
Start Etcher application
Select firmware file
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.
- 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.
- 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.
# Gateway Factory Reset
Prepare SD card with latest firmware as described in Creating Bootable SD Card with Gateway Firmware.
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
Turn ON the Gateway.
Wait for 1 minute while booting the system.
Insert the USB Flash Stick into the Gateway.
Wait for 15 seconds.
Pull out the USB Flash Stick.
Wait for 2 minutes while the Gateway rebooting.
Check if Gateway Factory Reset was done properly: the txt file
commands.txt
on the USB Flash Stick should contain:
hard_reset = false
- 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.
- Web CLI connection is available from device's page on https://cloud.enapter.com (opens new window).
- Basic CLI available by connecting Keyboard/Video/Mouse to the Gateway.
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 thecommit
command, or enterexit
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
- Connect to mqtt on gateway ip address, specified port, with specified username & password,
- 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
- Connect to mqtt on gateway ip address, specified port, with specified username & password,
- 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
.
- Define variable
set variables variable start-els type bool
commit
save
- Activate ELs plugin
set rule-engine plugin electrolyser-v21 enabled true
commit
save
exit
- 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
- 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.
- Define variable
set variables variable target-pressure type float
commit
save
- Activate ELs and dryers plugins
set rule-engine plugin electrolyser-v21 enabled true
set rule-engine plugin dryer enabled true
commit
save
exit
- 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
- 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 Cloudnotify-offline true
- if no connection between gateway and cloud - Heartbeat will not be sentperiod
- 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.
- Enter configuration mode:
[bd0745] $ configure
[bd0745] conf #
- Enable plugin:
[bd0745] conf # set rule-engine plugin electrolyser-v21 enabled true
[bd0745] conf #
- Save configuration and restart configuration
[bd0745] conf # commit
[bd0745] conf # save
[bd0745] conf # exit
[bd0745] $ configure
[bd0745] conf #
- 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 #
- 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 #
- 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:~$