Skip to main content

Write Blueprint

Enapter Blueprint

Enapter Blueprints is a technology that backs all device integrations in the Enapter EMS including our own devices — electrolysers, dryers, and others. By 2025 we have more than 50 energy device manufacturers already integrated. We noticed simple yet powerful patterns that repeat over and over in such integrations and we extracted them in a user-friendly set of tools under the common name — Blueprint.

Every device we integrate fits into a simple unified model which consists of properties, telemetry, commands, alerts and configuration. Describe your device in these terms and the platform will know what it capable of:

  • which charts can be shown on a telemetry dashboard,
  • which commands can be executed,
  • when to notify you about device alerts,
  • and how the device can interact with other parties of an energy system.

The minimal blueprint consists of two components:

  • The Manifest defines your device interface and capabilities. It's always represented as a manifest.yml file.
  • UCM Lua Script implements the logic required for communication with your endpoint device. Usually you'll find it as a ucm.lua file.

Example Device

For the purpose of this tutorial we are implementing a simple blueprint for a fictional gas sensor.

Writing manifest

YAML Format

The file is based on YAML standard which is sensible to lines indentation. We highly recommend using a text editor or an IDE with YAML support.

First of all we need to define our device in Enapter EMS. Open you favourite text editor or an IDE and insert the following code:

manifest.yml
# Blueprint specification version
blueprint_spec: device/3.0

display_name: Gas Sensor
description: Tutorial example of gas sensor.
icon: enapter-gauge

# Runtime describes how to run the device
runtime:
type: lua
options:
file: main.lua

# Configuration lists parameters required for the device to work as expected.
configuration:
# A configuration logical group describing device-specific parameters
sensor:
display_name: Sensor
description: Sensor settings.
parameters:
gas_type:
display_name: Gas Type
type: string
required: true
enum:
h2:
display_name: Hydrogen
o2:
display_name: Oxygen
co2:
display_name: Carbon Dioxide

# Properties are metadata that does not change during device normal operation
properties:
# Property reference name
serial_number:
# Property type, one of: boolean, float, integer, string
type: string
display_name: Serial Number
gas_type:
type: string
display_name: Detectable Gas Type


# Sensors data and internal device state, operational data
telemetry:
# Telemetry attribute reference name
status:
# Attribute type, one of: boolean, float, integer, string
type: string
display_name: Device Status
# Enum values for string attribute
enum:
ok:
display_name: OK
color: green
error:
display_name: Error
color: red
gas_concentration:
type: float
# Unit of measurement
unit: "%"
display_name: Gas Concentration

# Alerts which the device can raise during operation
alerts:
# Alert reference name
high_concentration_alarm:
# Alert severity, one of: info, warning, error.
severity: error
display_name: High Gas Concentration
description: Gas leakage is detected.

# Commands which can be performed on the device
commands:
# Command reference name
beep:
display_name: Beep
# Command group name (declared below)
group: checks
ui:
# Command icon to show in a user interface
icon: bell-ring-outline
# Show command in quick access list on mobile
quick_access: true
silence:
display_name: Silence
group: checks
ui:
icon: bell-off-outline
quick_access: true

# Commands can be grouped in the UI
command_groups:
checks:
display_name: Checks

Please check the full manifest reference out to find out about all the capabilites.

Lua Script

Lua script implements device interface declared in the manifest file using Lua programming language. Device communication APIs exposed to Lua depend on a UCM model and communication standard it supports. For this tutorial we skip everything related to communication with the connected device and just return sample properties and telemetry.

Create a new main.lua file, copy the following code and insert into the file.

main.lua
-- The entrypoint to your code, called automatically
function enapter.main()
-- Register periodic function, will send properties every 30 seconds
scheduler.add(30000, send_properties)
-- Register periodic function, will send telemetry every 1 second
scheduler.add(1000, send_telemetry)

-- Register 'beep' and 'silence' commands, the function passed as a second argument
-- will be executed every time user starts the command from UI
enapter.register_command_handler('beep', beep_command)
enapter.register_command_handler('silence', silence_command)
end

-- Store active alerts and status as a global array
-- Empty array means there are no alerts by default
active_alerts = {}
status = 'ok'

-- Obtain device properties and send it to Enapter EMS
function send_properties()
-- Read 'sensor' configuration to get a gas type
local config, err = configuration.read('sensor')
if err ~= nil then
enapter.log('read sensor configuration: ' .. err, 'error')
return
end

-- If config is not set, do not send properties
if not configuration.is_all_required_set('sensor') then
return
end

enapter.send_properties({
-- We use constant value for the example simplicity
serial_number = 'AC001215',
gas_type = config.gas_type,
})
end

-- Obtain device telemetry attributes and send it to Enapter EMS
function send_telemetry()
enapter.send_telemetry({
-- Again, we use constant value for simplicity
gas_concentration = 0.01,
status = status,
-- Pass active_alerts into telemetry
alerts = active_alerts,
})
end

-- 'beep' command implementation
function beep_command(ctx, args)
-- Add h2_high to active alerts array
active_alerts = { 'high_concentration_alarm' }
status = 'error'
-- Send some reply back to the user as a text message
return 'Sound alarm started'
end

-- 'silence' command implementation
function silence_command(ctx, args)
-- Clean active alerts array and reset device status
active_alerts = {}
status = 'ok'
return 'Sound alarm stopped'
end

Please check the full Lua API reference out to find out about all the capabilites.

All Rights Reserved © 2026 Enapter AG.