# Chapter 5: Rule Engine programming guide

# Overview

(to be added)

# 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

# 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 DR 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 if "online and device:is_running() and state.value == 'steady' or stack_amp_avg(45) > 12.5"

# Enapter Electrolyser V2.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

# 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 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 normaly 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 BE24AADBEB35CB53814620E1CA98D6A4F9DBC72F
set el21-heartbeat notify-offline true
set el21-heartbeat period 30

# Plug Power Fuel Cell

# Activation Plugin

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

# Available Actions

Action Description
start-fuel-cell Start Fuel Cell command
stop-fuel-cell Stop Fuel Cell command
start-fuel-cell-group Start Fuel Cell group command
stop-fuel-cell-group Stop Fuel Cell group command

# Expressions Available in Conditions

Expression Description Values
online Device online status boolean
state.value Fuel Cell state one of RUN, STANDBY
state.seconds_in_state Number of seconds in current state integer
volt Fuel Cell DC bus voltage (in volts) float
volt_avg(10) Fuel Cell DC bus voltage (in volts) 10 seconds average float
amp Fuel Cell DC bus amperage (in amps) float
amp_avg(10) Fuel Cell DC bus amperage (in amps) 10 seconds average float
watt Fuel Cell current power output (in watt) float
watt_avg(10) Fuel Cell current power output (in watt) 10 seconds average float
device:is_running() Whether fuel cell currently running or not boolean

# Example

[d0a09d] conf # set rule-engine rule 10 condition 10 fuel-cell FC1 if "state.value == 'RUN' and state.seconds_in_state > 300"

# Victron Multiplus Inverter Plugin

# Activation Plugin

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

# Expressions Available in Conditions

Expression Description Values
online Device online status boolean
state.value Inverter state one of down, startup, off, device_in_slave_mode, invert_full, invert_half, invert_aes, power_assist, bypass, charge_initializing, charge_bulk, charge_absorption, charge_float, charge_storage, charge_repeated_absorption, charge_forced_absorption, charge_equalise, charge_bulk_stopped
state.seconds_in_state Number of seconds in current state integer
ac_l1_voltage AC L1 Voltage float
ac_l1_voltage_avg(10) AC L1 Voltage 10 seconds average float
ac_l1_amperage AC L1 Amperage float
ac_l1_amperage_avg(10) AC L1 Amperage 10 seconds average float
ac_amperage AC Amperage float
ac_amperage_avg(10) AC Amperage 10 seconds average float
ac_freq AC Frequency float
ac_freq_avg(10) AC Frequency 10 seconds average float
dc_voltage DC Voltage float
dc_voltage_avg(10) DC Voltage 10 seconds average float
dc_amperage DC Amperage float
dc_amperage_avg(10) DC Amperage 10 seconds average float
grid_l1_freq Grid L1 Frequency float
grid_l1_freq_avg(10) Grid L1 Frequency 10 seconds average float
grid_l1_voltage Grid L1 Voltage float
grid_l1_voltage_avg(10) Grid L1 Voltage 10 seconds average float
grid_l1_amperage Grid L1 Amperage float
grid_l1_amperage_avg(10) Grid L1 Amperage 10 seconds average float

# Example

[d0a09d] conf # set rule-engine rule 10 condition 10 victron-multiplus VMP if "dc_voltage_avg(120) < 42 and (state.value == 'invert_full' or state.value == 'invert_half')"

# 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

# IE Fuel Cell Plugin

# Activation Plugin

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

# Device definition

IE Fuel Cell integration requires two modules. One LUA module for collecting telemetry and relay module for start/stop operations.

[d0a09d] $ configure
[d0a09d] conf # set rule-engine devices ie-fuel-cell TELEMETRY_MODULE_HARDWARE_ID enabled "true"
[d0a09d] conf # set rule-engine devices ie-fuel-cell TELEMETRY_MODULE_ID rl6id "RL6_MODULE_HARDWARE_ID"
[d0a09d] conf # save
[d0a09d] conf # commit
[d0a09d] conf # exit

# Expressions Available in Conditions

Expression Description Values
online Device online status boolean
state.value Fuel Cell state one of inactive, steady, run, fault
state.seconds_in_state Number of seconds in current state integer
volt Fuel Cell DC bus voltage (in volts) float
volt_avg(10) Fuel Cell DC bus voltage (in volts) 10 seconds average float
amp Fuel Cell DC bus amperage (in amps) float
amp_avg(10) Fuel Cell DC bus amperage (in amps) 10 seconds average float
watt Fuel Cell current power output (in watt) float
watt_avg(10) Fuel Cell current power output (in watt) 10 seconds average float
device:is_running() Whether fuel cell currently running or not boolean

# Available Actions

Action Description
start-fuel-cell Start Fuel Cell command
stop-fuel-cell Stop Fuel Cell command

# 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 RL1 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.

So the most simple Lua condition will be:

return true

# Multiple Electrolysers and Single Dryer Management Example for EL2.0 and DR

[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 EL1 enabled true
[d0a09d] conf # set rule-engine devices electrolyser EL1 power 2400
[d0a09d] conf # set rule-engine devices electrolyser EL2 enabled true
[d0a09d] conf # set rule-engine devices electrolyser EL2 power 2400
[d0a09d] conf # set rule-engine devices dryer DR enabled "true"
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-management dryer DR
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-management electrolyser EL1
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-management electrolyser EL2

# Multiple Electrolysers and Single Dryer with pid regulation Example for EL2.1 and DR

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 DR enabled "true"
[d0a09d] conf # set rule-engine devices electrolyser-v21 EL1 enabled "true"
[d0a09d] conf # set rule-engine devices electrolyser-v21 EL1 power "2400"
[d0a09d] conf # set rule-engine devices electrolyser-v21 EL2 enabled "true"
[d0a09d] conf # set rule-engine devices electrolyser-v21 EL2 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 DR
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-mgmt electrolyser EL1
[d0a09d] conf # set rule-engine dryer-management-rule 100-dryer-mgmt electrolyser EL2
[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 DR
[d0a09d] conf # set rule-engine groups electrolyser-v21 PID-ELS device EL1
[d0a09d] conf # set rule-engine groups electrolyser-v21 PID-ELS device EL2