This is the complete reference for scripting in the Edge-EMS Builder expression engine: aggregation expressions, trigger conditions/actions, post-processing actions, and MQTT publish/subscribe content. Scripts use Lua 5.x , parsed and executed by the built-in Lua runtime. Start with the expression engine for an introduction. This page supplies the complete built-in modules, global function signatures, and return-value conventions.
⚠️ If you used an early Java version of Edge-EMS Builder with the QLExpress4 engine and Java-like syntax, note that ${...} variable references remain largely unchanged, while script bodies now use standard Lua. Examples: new ArrayList() → {}, .add(x) → table.insert(t, x), new HashMap() → {}, .put(k, v) → t[k] = v. Most built-in function names remain; use this page as a migration reference.
Language : Lua 5.x; function names and placeholders are case-sensitive.
Data placeholders : the engine replaces ${dataKey} with the current value before execution; use ${[deviceCode]dataKey} across devices.
Sentinel : unavailable data is injected as the string __Null__. Compare explicitly or use isNull / isNotNull; use tonumber before numerical calculations.
Return values vary by context , as described below. Incorrect return types are the most common source of configuration errors.
Module functions require require("module-name") before use. Global functions , such as buildCommonWriteMap and jsonToMap, can be called directly without require.
Logging : Logger defaults to WARN, so only Logger.warn() / Logger.error() actually produce output. Do not rely solely on Logger.info()/Logger.debug() when debugging.
Syntax
Description
${variable}
Returns the current value
${variable[-1s]}
Returns the value 1 second ago
${variable[-5s]}
Returns the value 5 seconds ago
${variable[raw]}
Injects the value unchanged without automatic type conversion. For ambiguous values such as numeric 1000 and binary 1000, use raw to control unchanged input. [raw] must appear last and nowhere else.
${[deviceA]variable}
Returns the value from shared device deviceA
${variable[@timestamp]}
Returns the value at a specified absolute time
${variable[#N]}
Returns the Nth most recent historical value; without this rule, returns the latest value
${[deviceA]variable[-5s][#N]}
Returns the Nth most recent sample from shared device deviceA as of 5 seconds ago
When a target point has no value, the engine injects the sentinel string __Null__. Check explicitly, for example: if ${some_key} == "__Null__" then ... end.
Different script locations require entirely different return values. This is a frequent source of errors:
Context
Configuration location
Required return value
Trigger condition
Trigger-condition expression
A single Boolean ; true means the condition is satisfied
Trigger action: expression-type scheme
Action content (Expression)
Array table with consecutive indices starting at 1, containing maps returned by functions such as buildCommonWriteMap(...); empty table {} means no write items
Trigger action: mixed-write scheme
Action individually bound to each dataKey
A single value (string/number/Boolean) to write to that dataKey; do not return a buildCommonWriteMap array
Post-processing action
Cleanup script after trigger-action execution
Array table of write descriptors , as for expression-type actions. Inspect the main execution result through fixed variables ${trigger_result} (Boolean) and ${trigger_write_result} (JSON string requiring jsonToMap)
Aggregation point expression
Aggregation calculation expression
A single value , such as a number or string, as the point’s latest value
MQTT publication content (publishContent)
MQTT publish configuration
Lua table , serialized as JSON for the publication payload
MQTT subscription action (actionContent)
MQTT subscribe configuration
Array table of write descriptors , as for expression-type trigger actions
MQTT response topic (responseTopic)
MQTT subscribe configuration
A single string used as the response publication topic
MQTT response content (response)
MQTT subscribe configuration
Strings are sent unchanged ; other values, such as Lua tables, are serialized as JSON
Each script call has an execution timeout, 10 seconds by default. Exceeding it fails that execution. Avoid unbounded historical queries or HTTP requests inside loops.
The following modules require require("module-name") before use.
A complete date/time module supporting time zones, formatting, arithmetic, and more.
local OffsetDateTime = require ( " OffsetDateTime " )
Method
Description
Return value
new()
Create the current time
OffsetDateTime
new(sec, nsec?)
Create from a Unix timestamp
OffsetDateTime
now()
Get the current time
OffsetDateTime
parse(str)
Parse a time string
OffsetDateTime | (nil, err)
parseInLocation(str, location)
Parse time in a specified time zone
OffsetDateTime | (nil, err)
unix(sec, nsec?)
Create from Unix seconds
OffsetDateTime
unixMilli(msec)
Create from a millisecond timestamp
OffsetDateTime
unixMicro(usec)
Create from a microsecond timestamp
OffsetDateTime
Method
Description
Return value
year()
Get year
number
month()
Get month (1–12)
number
day()
Get day of month (1–31)
number
hour()
Get hour (0–23)
number
minute()
Get minute (0–59)
number
second()
Get second (0–59)
number
nanosecond()
Get nanoseconds
number
yearDay()
Get day of year
number
weekday()
Get weekday (0 = Sunday)
number
isoWeek()
Get ISO week information
{year, week}
date()
Get year, month, and day
{year, month, day}
clock()
Get hour, minute, and second
{hour, minute, second}
Method
Description
Return value
add(durationStr)
Add a duration
OffsetDateTime | (nil, err)
addDate(years, months, days)
Add years, months, and days
OffsetDateTime
sub(other)
Calculate time difference in nanoseconds
number
addYears(n)
Add years
OffsetDateTime
addMonths(n)
Add months
OffsetDateTime
addDays(n)
Add days
OffsetDateTime
addHours(n)
Add hours
OffsetDateTime
addMinutes(n)
Add minutes
OffsetDateTime
addSeconds(n)
Add seconds
OffsetDateTime
addMilliseconds(n)
Add milliseconds
OffsetDateTime
addMicroseconds(n)
Add microseconds
OffsetDateTime
addNanoseconds(n)
Add nanoseconds
OffsetDateTime
Method
Description
Return value
diffYears(other)
Difference in years
number
diffMonths(other)
Difference in months
number
diffDays(other)
Difference in days
number
diffHours(other)
Difference in hours
number
diffMinutes(other)
Difference in minutes
number
diffSeconds(other)
Difference in seconds
number
Method
Description
Return value
equal(other)
Whether equal
boolean
before(other)
Whether earlier
boolean
after(other)
Whether later
boolean
isZero()
Whether the zero value
boolean
Method
Description
Return value
isToday()
Whether today
boolean
isYesterday()
Whether yesterday
boolean
isTomorrow()
Whether tomorrow
boolean
isThisWeek()
Whether this week
boolean
isThisMonth()
Whether this month
boolean
isThisYear()
Whether this year
boolean
isBetween(start, end)
Whether within the range
boolean
isInRange(start, end)
Whether within the range
boolean
Method
Description
Return value
format(layout)
Custom formatting
string
toString()
Convert to string
string
toDateTimeString()
Date/time format
string
toDateString()
Date format
string
toTimeString()
Time format
string
toYearString()
Year
string
toMonthString()
Month
string
toDayString()
Day
string
toHourString()
Hour
string
toMinuteString()
Minute
string
toSecondString()
Second
string
Method
Description
Return value
unix()
Unix timestamp in seconds
number
unixMilli()
Unix timestamp in milliseconds
number
unixMicro()
Unix timestamp in microseconds
number
unixNano()
Unix timestamp in nanoseconds
number
Method
Description
Return value
utc()
Convert to UTC
OffsetDateTime
local()
Convert to local time zone
OffsetDateTime
in(location)
Convert to specified time zone
OffsetDateTime | (nil, err)
Method
Description
Return value
truncate(durationStr)
Truncate to specified precision
OffsetDateTime | (nil, err)
round(durationStr)
Round to specified precision
OffsetDateTime | (nil, err)
toTime()
Convert to Go time.Time
time.Time
local layouts = OffsetDateTime .Layout
-- layouts.DateTime = "2006-01-02 15:04:05"
-- layouts.Date = "2006-01-02"
-- layouts.Time = "15:04:05"
local OffsetDateTime = require ( " OffsetDateTime " )
local Logger = require ( " Logger " )
local now = OffsetDateTime . now ()
Logger . warn ( now : toString ())
local dt = OffsetDateTime . parse ( " 2024-01-15T10:30:00.000Z " )
Logger . warn ( " 年份: " .. dt : year ())
Logger . warn ( " 月份: " .. dt : month ())
local tomorrow = now : addDays ( 1 )
local nextWeek = now : addDays ( 7 )
Logger . warn ( " 明天: " .. tomorrow : toDateString ())
local hours = nextWeek : diffHours ( now )
Logger . warn ( " 相差小时: " .. hours )
Logger . warn ( now : format ( " 2006-01-02 15:04:05 " ))
Logger . warn ( now : toDateTimeString ())
A time type containing hours, minutes, and seconds, without a date or time zone.
local LocalTime = require ( " LocalTime " )
Method
Description
Return value
new(hour, minute, second)
Create a time
LocalTime | (nil, err)
now()
Get the current time
LocalTime
parse(str)
Parse “HH:mm:ss”
LocalTime | (nil, err)
fromTime(time.Time)
Create from time.Time
LocalTime | (nil, err)
fromDuration(durationStr)
Create from a duration
LocalTime | (nil, err)
Method
Description
Return value
hour()
Get hour
number
minute()
Get minute
number
second()
Get second
number
toString()
Convert to “HH:mm:ss”
string
toDuration()
Convert to duration string
string
equal(other)
Whether equal
boolean
before(other)
Whether earlier
boolean
after(other)
Whether later
boolean
beforeOrEqual(other)
Whether earlier or equal
boolean
afterOrEqual(other)
Whether later or equal
boolean
isZero()
Whether 00:00:00
boolean
diffSeconds(other)
Difference in seconds
number
diffMinutes(other)
Difference in minutes
number
diffHours(other)
Difference in hours
number
addSeconds(n)
Add seconds
LocalTime
addMinutes(n)
Add minutes
LocalTime
addHours(n)
Add hours
LocalTime
subSeconds(n)
Subtract seconds
LocalTime
subMinutes(n)
Subtract minutes
LocalTime
subHours(n)
Subtract hours
LocalTime
local LocalTime = require ( " LocalTime " )
local Logger = require ( " Logger " )
local workStart = LocalTime . new ( 9 , 0 , 0 ) -- 09:00:00
local workEnd = LocalTime . new ( 17 , 30 , 0 ) -- 17:30:00
local now = LocalTime . now ()
Logger . warn ( " 当前时间: " .. now : toString ())
if now : isBetween ( workStart , workEnd ) then
local breakTime = workStart : addHours ( 3 ): addMinutes ( 30 ) -- 12:30:00
Logger . warn ( " 午休时间: " .. breakTime : toString ())
local workHours = workEnd : diffHours ( workStart )
Logger . warn ( " 工作时长: " .. workHours .. " 小时 " )
Logging module integrated with system logs.
local Logger = require ( " Logger " )
Method
Description
Parameters
info(msg)
Output an INFO log
string
warn(msg)
Output a WARN log
string
error(msg)
Output an ERROR log
string
debug(msg)
Output a DEBUG log
string
infof(fmt, ...)
Formatted INFO log
string, …
warnf(fmt, ...)
Formatted WARN log
string, …
errorf(fmt, ...)
Formatted ERROR log
string, …
debugf(fmt, ...)
Formatted DEBUG log
string, …
local Logger = require ( " Logger " )
Logger . debug ( " 变量值: x=10 " )
Logger . infof ( " 用户 %s 执行操作: %s " , user , action )
Logger . warnf ( " 重试次数: %s " , 3 )
Note: Edge-EMS Builder defaults to WARN logging. Only WARN and ERROR logs are output.
JSON serialization, deserialization, and manipulation, based on bytedance/sonic.
local JSON = require ( " JSON " )
Method
Description
Return value
encode(value)
Serialize to JSON
string | (nil, err)
decode(text)
Deserialize
table | (nil, err)
Method
Description
Return value
toJSONString(value)
Serialize without returning an error
string
toJSONStringIndent(value, prefix?, indent?)
Serialize with formatting
string
toMap(jsonStr)
Convert to map
table | (nil, err)
toStringMap(jsonStr)
Convert to string map
table | (nil, err)
toSlice(jsonStr)
Convert to array
table | (nil, err)
isValid(jsonStr)
Validate JSON format
boolean
pretty(jsonStr)
Pretty-print JSON
string
merge(json1, json2)
Merge two JSON values
string | (nil, err)
get(jsonStr, key)
Get a value
any | (nil, err)
set(jsonStr, key, value)
Set a value
string | (nil, err)
remove(jsonStr, key)
Remove a key
string | (nil, err)
clone(value)
Deep copy
any | (nil, err)
local JSON = require ( " JSON " )
local Logger = require ( " Logger " )
-- Basic serialization/deserialization
local obj = { name = " 张三 " , age = 30 , tags = { " developer " , " golang " }}
local jsonStr = JSON . encode ( obj )
Logger . warn ( jsonStr ) -- {"name":"张三","age":30,"tags":["developer","golang"]}
local decoded , err = JSON . decode ( jsonStr )
Logger . warn ( " 解析失败: " .. err )
Logger . warn ( " 姓名: " .. decoded .name)
local pretty = JSON . pretty ( jsonStr )
if JSON . isValid ( jsonStr ) then
local newJson = JSON . set ( jsonStr , " city " , " 北京 " )
Logger . warn ( newJson ) -- {"name":"张三","age":30,"tags":[...],"city":"北京"}
local age = JSON . get ( newJson , " age " )
Logger . warn ( " 年龄: " .. age ) -- 30
local removed = JSON . remove ( newJson , " age " )
Logger . warn ( removed ) -- {"name":"张三","tags":[...],"city":"北京"}
local merged = JSON . merge ( json1 , json2 )
Logger . warn ( merged ) -- {"a":1,"b":2}
local original = { data = { x = 10 }}
local copied = JSON . clone ( original )
Regular-expression module supporting matching, searching, replacement, and splitting.
local Regex = require ( " Regex " )
Method
Description
Return value
match(text, pattern)
Whether the pattern matches
boolean
findAll(text, pattern, limit?)
Find all matches, including capture groups
{{full, g1, g2, …}, …} | (nil, err)
replace(text, pattern, repl)
Replace, supporting group references such as $1
string | (nil, err)
split(text, pattern, limit?)
Split by regular expression
{string, …} | (nil, err)
isEmail(text)
Whether an email address
boolean
isPhone(text)
Whether a mobile phone number in China
boolean
isIP(text)
Whether an IP address
boolean
isURL(text)
Whether a URL
boolean
local Regex = require ( " Regex " )
local Logger = require ( " Logger " )
if Regex . match ( " abc123 " , " \\ d+ " ) then
-- Find all matches, including capture groups
local matches = Regex . findAll ( " a1 b22 c333 " , " ( \\ w)( \\ d+) " )
-- matches = {{"a1","a","1"}, {"b22","b","22"}, {"c333","c","333"}}
for i , m in ipairs ( matches ) do
Logger . warn ( " 匹配 " .. i .. " : " .. m [ 1 ] .. " , 字母= " .. m [ 2 ] .. " , 数字= " .. m [ 3 ])
-- Replace, supporting group references
local s = Regex . replace ( " abc-123-def " , " ( \\ d+) " , " [$1] " )
Logger . warn ( s ) -- "abc-[123]-def"
local parts = Regex . split ( " a,b,,c " , " , " , - 1 )
-- parts = {"a", "b", "", "c"}
for i , p in ipairs ( parts ) do
Logger . warn ( " 部分 " .. i .. " : ' " .. p .. " ' " )
Logger . warn ( Regex . isEmail ( " test@example.com " )) -- true
Logger . warn ( Regex . isPhone ( " 13812345678 " )) -- true
Logger . warn ( Regex . isIP ( " 192.168.1.1 " )) -- true
Logger . warn ( Regex . isURL ( " https://example.com " )) -- true
String-processing utilities.
local String = require ( " String " )
Method
Description
Return value
trim(s)
Remove leading and trailing whitespace
string
upper(s)
Convert to uppercase
string
lower(s)
Convert to lowercase
string
contains(s, sub)
Whether it contains a substring
boolean
startsWith(s, prefix)
Whether it starts with the prefix
boolean
endsWith(s, suffix)
Whether it ends with the suffix
boolean
local String = require ( " String " )
local s = " Hello World "
Logger . warn ( String . trim ( s )) -- "Hello World"
Logger . warn ( String . upper ( s )) -- " HELLO WORLD "
Logger . warn ( String . lower ( s )) -- " hello world "
Logger . warn ( String . contains ( " hello " , " ll " )) -- true
Logger . warn ( String . startsWith ( " hello " , " he " )) -- true
Logger . warn ( String . endsWith ( " hello " , " lo " )) -- true
Mathematical utilities.
local Math = require ( " Math " )
Method
Description
Return value
round(n)
Round to nearest integer
number
floor(n)
Round down
number
ceil(n)
Round up
number
abs(n)
Absolute value
number
max(a, b)
Maximum
number
min(a, b)
Minimum
number
local Math = require ( " Math " )
Logger . warn ( Math . round ( 3.6 )) -- 4
Logger . warn ( Math . floor ( 3.9 )) -- 3
Logger . warn ( Math . ceil ( 3.1 )) -- 4
Logger . warn ( Math . abs ( - 5 )) -- 5
Logger . warn ( Math . max ( 10 , 20 )) -- 20
Logger . warn ( Math . min ( 10 , 20 )) -- 10
Table utilities supporting traversal of arrays and key/value pairs.
local TableUtils = require ( " TableUtils " )
Method
Description
Return value
keys(tbl)
Get all keys
{string, …}
values(tbl)
Get all values
{any, …}
map(tbl, fn)
Map using fn(value, key)
{any, …}
filter(tbl, fn)
Filter using fn(value, key)
{any, …}
reduce(tbl, fn, init)
Reduce using fn(acc, value, key)
any
sortBy(tblOfMaps, key)
Stable sort by key
{map, …}
local T = require ( " TableUtils " )
local obj = { a = 1 , b = 2 , c = 3 }
local keys = T . keys ( obj ) -- {"a", "b", "c"}
local values = T . values ( obj ) -- {1, 2, 3}
local doubled = T . map ( arr , function ( v , i )
local mapped = T . map ({ a = 1 , b = 2 }, function ( v , k )
-- mapped = {"a:1", "b:2"}
local arr = { 1 , 2 , 3 , 4 , 5 }
local even = T . filter ( arr , function ( v , i )
local sum = T . reduce ({ 1 , 2 , 3 }, function ( acc , v , i )
local sorted = T . sortBy ( users , " age " )
-- sorted = {{name="李四",age=25}, {name="张三",age=30}, {name="王五",age=35}}
These functions are registered directly in global scope and do not require require.
Function
Purpose
cp56Time2aToOffsetDateTime(hex[, byteOrder])
Decode IEC 60870-5 time and return OffsetDateTime
offsetDateTimeToCP56Time2a(time[, byteOrder])
Encode time as a hexadecimal payload
byteOrder supports AB / BA and defaults to standard AB when omitted. Explicit byte order supports four-register payloads; ambiguous zero-padding positions return an error. Check the device’s register layout.
Function
Description
Return value
jsonToMap(str)
Convert JSON to map
table | (nil, err)
jsonToList(str)
Convert JSON to list
table | (nil, err)
jsonToListMap(str)
Convert JSON to list of maps
table | (nil, err)
completeDateTime(str)
Complete a date/time string
string | (nil, err)
quoteJson(str)
Escape JSON quotes
string
simpleUUID()
Generate a simple UUID
string
convertString(str)
Convert a string’s type
any
isNull(any)
Check whether a value is null
bool
isNotNull(any)
Check whether a value is not null
bool
isNull treats nil, empty strings, case-insensitive “null”, and the sentinel __Null__ as null. Lua’s or 0 does not handle that sentinel.
local Logger = require ( " Logger " )
local map , err = jsonToMap ( ' {"a":1,"b":2} ' )
local list = jsonToList ( ' [1,2,3] ' )
local fullTime = completeDateTime ( " 2024-01-15 " )
-- fullTime = "2024-01-15T00:00:00.000+08:00"
Logger . warn ( id ) -- 32-character UUID string
Function
Description
Return value
getLatestDataValue(dataKey)
Get the latest data value
any
getAccountCache(key)
Get account cache
any
getEMSDataCache(key)
Get EMS data cache
any
getShareCache(key)
Get shared cache
any
getMqttCache(key)
Get MQTT cache
any
getTriggerCache(key)
Get trigger cache
any
getDeviceShareValue(deviceCode, dataKey)
Get a device’s latest shared value by deviceCode and dataKey
string | nil
getDeviceShareValues(deviceCodes, dataKey)
Get each device’s latest value from a device list and dataKey
table
getAllDeviceShareValues(dataKey)
Get the latest value for dataKey from every device in the shared space
table
local Logger = require ( " Logger " )
-- Get the latest device data
local value = getLatestDataValue ( " device1.temperature " )
Logger . warn ( " 当前温度: " .. value )
-- Get account information
local account = getAccountCache ( " user123 " )
Logger . warn ( " 用户名: " .. account .username)
local sharedData = getShareCache ( " shared_config " )
-- Get the latest shared value from one device
local val = getDeviceShareValue ( " device1 " , " temperature " )
Logger . warn ( " 设备 device1 温度: " .. val )
-- Get shared values for each device in a device list
local deviceCodes = { " device1 " , " device2 " }
local shareValues = getDeviceShareValues ( deviceCodes , " temperature " )
for deviceCode , dataValue in pairs ( shareValues ) do
Logger . warn ( " 设备 " .. deviceCode .. " 温度: " .. dataValue )
-- Get shared values from all devices
local allShareValues = getAllDeviceShareValues ( " temperature " )
for deviceCode , dataValue in pairs ( allShareValues ) do
Logger . warn ( " 设备 " .. deviceCode .. " 温度: " .. dataValue )
These functions scan the local latest-value cache, filter dataKeys by prefix, suffix, or keyword, and return matching point information as a {dataKey: FrontDataDTO} table.
Return fields : each value is a FrontDataDTO object with these common fields:
Field
Type
Description
DataKey
string
Unique data key
DataValue
string
Latest value
DataType
string
Data type
DataName
string
Data name
DataUnit
string
Unit
CollectionTime
OffsetDateTime
Acquisition time
Note : nil means no matching cache entries. dataType must exactly match an enumeration: Collection / Customization / Aggregation / Share.
Function
Description
Return value
getLatestDataValuesBySuffix(dataType, suffix)
Latest values of the specified type whose dataKey ends with suffix
table | nil
getAllLatestDataValuesBySuffix(suffix)
Latest values of all types whose dataKey ends with suffix
table | nil
Function
Description
Return value
getLatestDataValuesByPrefix(dataType, prefix)
Latest values of the specified type whose dataKey starts with prefix
table | nil
getAllLatestDataValuesByPrefix(prefix)
Latest values of all types whose dataKey starts with prefix
table | nil
Function
Description
Return value
getLatestDataValuesByPrefixAndSuffix(dataType, prefix, suffix)
Latest values of the specified type whose dataKey matches both prefix and suffix
table | nil
getAllLatestDataValuesByPrefixAndSuffix(prefix, suffix)
Latest values of all types whose dataKey matches both prefix and suffix
table | nil
Function
Description
Return value
getLatestDataValuesByFuzzy(dataType, keyword)
Latest values of the specified type whose dataKey contains keyword
table | nil
getAllLatestDataValuesByFuzzy(keyword)
Latest values of all types whose dataKey contains keyword
table | nil
local Logger = require ( " Logger " )
-- Query latest acquisition values whose keys end with "_power"
local powerValues = getLatestDataValuesBySuffix ( " Collection " , " _power " )
for dataKey , dto in pairs ( powerValues ) do
Logger . warn ( dataKey .. " = " .. dto .DataValue)
-- Query latest values ending with "_power" across all data types
local allPower = getAllLatestDataValuesBySuffix ( " _power " )
-- Query all acquisition data starting with "meter1."
local meterValues = getLatestDataValuesByPrefix ( " Collection " , " meter1. " )
for dataKey , dto in pairs ( meterValues ) do
Logger . warnf ( " %s = %s (%s) " , dataKey , dto .DataValue, dto .DataUnit)
-- Query data starting with "meter1." across all types
local allMeter = getAllLatestDataValuesByPrefix ( " meter1. " )
-- Query acquisition data whose dataKey starts with "meter1." and ends with "_voltage"
local voltages = getLatestDataValuesByPrefixAndSuffix ( " Collection " , " meter1. " , " _voltage " )
-- Query data matching both prefix and suffix across all types
local allVoltages = getAllLatestDataValuesByPrefixAndSuffix ( " meter1. " , " _voltage " )
-- Fuzzy search: latest aggregation values whose dataKey contains "temp"
local tempValues = getLatestDataValuesByFuzzy ( " Aggregation " , " temp " )
for dataKey , dto in pairs ( tempValues ) do
Logger . warn ( " 温度点位: " .. dataKey .. " = " .. dto .DataValue)
-- Fuzzy search: latest values whose dataKey contains "temp" across all types
local allTemp = getAllLatestDataValuesByFuzzy ( " temp " )
Function
Description
Return value
getDeviceList(ignoreLocal)
Get device list, excluding the local device when ignoreLocal=true
table
getDeviceCodeList(ignoreLocal)
Get deviceCode list, excluding the local device when ignoreLocal=true
table
local Logger = require ( " Logger " )
-- Get the complete device list
local allDevices = getDeviceList ( false )
for i , device in ipairs ( allDevices ) do
Logger . warn ( " 设备: " .. device .deviceCode .. " - " .. device .deviceName)
-- Get devices excluding the local device
local otherDevices = getDeviceList ( true )
for i , device in ipairs ( otherDevices ) do
Logger . warn ( " 共享设备: " .. device .deviceCode)
-- Get all device codes, faster than retrieving full device information
local deviceCodes = getDeviceCodeList ( false )
for i , code in ipairs ( deviceCodes ) do
Logger . warn ( " 设备编码: " .. code )
-- Get device codes excluding the local device
local otherDeviceCodes = getDeviceCodeList ( true )
Function
Description
Return value
getHistoryData(dataType, dataKey, startTime?, endTime?, formatMap?)
Get historical data
table
getShareHistoryData(deviceCode, dataKey, startTime?, endTime?, formatMap?)
Get shared historical data from the specified device
table
getTimeData(dataKey, time?, interval?)
Get data at a specified time
table
getShareTimeData(deviceCode, dataKey, time?, interval?)
Get shared data at a specified time
table
deleteCustomizationData(dataKey, startTime?, endTime?)
Delete custom data
boolean
Parameters :
startTime/endTime/time accepts:
OffsetDateTime objects, recommended.
Time strings, such as “2024-01-15T10:00:00.000Z”.
Abbreviated strings, such as “2024-01-15”, completed automatically.
formatMap: optional table customizing field names in returned results.
dataKey: custom data-key field name; default “dataKey”.
dataValue: custom data-value field name; default “dataValue”.
collectionTime: custom acquisition-time field name; default “collectionTime”.
Customization return fields :
The time fields returned by getHistoryData / getTimeData for Customization depend on schedule type:
DailyChange : availableTime as a full ISO 8601 date/time, and expiredTime.
DailyRepeat : availableTime and expiredTime as HH:mm:ss strings.
local OffsetDateTime = require ( " OffsetDateTime " )
local Logger = require ( " Logger " )
-- Method 1: use OffsetDateTime objects, recommended
local now = OffsetDateTime . now ()
local startTime = now : addDays ( - 7 )
local data = getHistoryData ( " Collection " , " temperature " , startTime , endTime )
-- Method 1 extension: customize returned field names with formatMap
local data = getHistoryData ( " Collection " , " temperature " , startTime , endTime , formatMap )
-- Method 2: use time strings
local data = getHistoryData ( " Collection " , " temperature " , " 2024-01-01T00:00:00.000Z " , " 2024-01-31T23:59:59.000Z " )
-- Method 3: use abbreviated strings, completed automatically
local data = getHistoryData ( " Collection " , " temperature " , " 2024-01-01 " , " 2024-01-31 " )
-- Query shared historical data
local sharedData = getShareHistoryData ( " space1 " , " pressure " , startTime , endTime )
-- Query data at a specified time
local value = getTimeData ( " temperature " , now , " 5m " )
local deleted = deleteCustomizationData ( " data1 " , startTime , endTime )
Logger . warn ( " 删除成功: " .. tostring ( deleted ))
Function
Description
Return value
buildCommonWriteMap(dataType, dataKey, dataValue, availableDate, expiredDate, changeMod)
Build a generic write map
table
buildGeneralWriteMap(dataType, dataKey, dataValue, changeMod)
Build a simplified generic write map without time parameters
table
buildCustomizationWriteMap(dataKey, dataValue, availableDate, expiredDate)
Build a DailyChange time-scheduled write map with implicit dataType=Customization
table
buildDailyRepeatWriteMap(dataKey, dataValue, availableTime, expiredTime)
Build a DailyRepeat time-scheduled write map with implicit dataType=Customization and HH:mm:ss time strings
table
updateDailyRepeatSchedule(dataKey, scheduleAvailableDate, scheduleExpiredDate)
Update the overall effective range of a DailyRepeat configuration; either date may be nil, meaning unrestricted or permanently effective
boolean
buildAlarmObservationMap(sourceCode, alarmKey, state, alarmType, alarmLevel, alarmContent[, detailKey])
Build an alarm-event observation; state is ACTIVE / NORMAL / UNKNOWN
table
buildCommonAlarmMap(alarmType, alarmContent)
Build a generic alarm map
table
buildMqttAlarmMap(alarmType, alarmContent, mqttConnectionConfigId, topic, qos)
Build an MQTT alarm map
table
buildSlaveWriteMap(deviceCode, dataType, dataKey, dataValue, availableDate, expiredDate, changeMod)
Build a slave-device write map
table
Alarm observations use a stable sourceCode + alarmKey. Send NORMAL for normal conditions and UNKNOWN for missing values or offline devices. Event states differ from observation states; see Alarm lifecycle for the full workflow. Legacy alarm constructors still create independent records.
CommBridge performs inverse coefficient conversion for acquisition writes. The old buildCollectionWriteMap has been removed. Use generic write constructors without repeating conversion.
Parameters :
dataType: Collection (acquisition), Customization (custom/time-scheduled), Aggregation, Share, or Alarm.
availableDate / expiredDate: required only for Customization of DailyChange type; ISO 8601 strings or OffsetDateTime objects. Pass nil for other types.
availableTime / expiredTime: required only for Customization of DailyRepeat type, formatted as "HH:mm:ss", such as "08:00:00"; must not cross midnight.
changeMod: Boolean; true writes only when the value changes.
local OffsetDateTime = require ( " OffsetDateTime " )
-- Write an acquisition point
local writeCollection = buildCommonWriteMap ( " Collection " , " temperature " , 25.5 , nil , nil , false )
-- Write a custom point: DailyChange with full date/time intervals
local writeCustom = buildCommonWriteMap (
" Customization " , " mode " , " 1 " ,
" 2024-01-15T07:00:00+08:00 " ,
" 2024-01-15T18:00:00+08:00 " ,
-- Write a custom point: DailyChange using its dedicated shorthand
local writeCustom2 = buildCustomizationWriteMap (
" 2024-01-15T07:00:00+08:00 " ,
" 2024-01-15T18:00:00+08:00 "
-- Write a custom point: DailyRepeat daily intervals in HH:mm:ss format
local writeDailyRepeat = buildDailyRepeatWriteMap ( " charge_mode " , " 1 " , " 08:00:00 " , " 18:00:00 " )
-- Update the overall effective range of a DailyRepeat configuration
local OffsetDateTime = require ( " OffsetDateTime " )
local ok = updateDailyRepeatSchedule ( " charge_mode " ,
OffsetDateTime . parse ( " 2026-01-01T00:00:00+08:00 " ),
OffsetDateTime . parse ( " 2026-12-31T23:59:59+08:00 " ))
-- Make permanently effective by passing nil for both dates
local ok2 = updateDailyRepeatSchedule ( " charge_mode " , nil , nil )
-- Set a start without an end; nil means never expires
local ok3 = updateDailyRepeatSchedule ( " charge_mode " , " 2026-01-01 " , nil )
-- Write an aggregation point: simplified form without time parameters
local writeAgg = buildGeneralWriteMap ( " Aggregation " , " avg_temp " , 22.5 , false )
-- Build an alarm to write a local alarm record
local alarm = buildCommonAlarmMap ( " TEMP_HIGH " , " 温度超过80°C " )
-- Build an MQTT alarm: bind an MQTT connection ID and report the alarm to the broker
local mqttAlarm = buildMqttAlarmMap ( " TEMP_HIGH " , " 温度超过80°C " , 1 , " alarm/upload " , 1 )
-- Write slave-device shared data
local slaveWrite = buildSlaveWriteMap ( " DeviceB " , " Share " , " shared_temp " , 25.5 , nil , nil , false )
Function
Description
Return value
toFixedLengthBinary(value, length)
Convert to fixed-length binary
string | (nil, err)
toDecimal(binaryStr)
Convert binary to decimal
number | (nil, err)
-- Convert decimal to binary
local binary = toFixedLengthBinary ( 10 , 8 )
Logger . warn ( binary ) -- "00001010"
-- Convert binary to decimal
local decimal = toDecimal ( " 00001010 " )
Logger . warn ( decimal ) -- 10
local Logger = require ( " Logger " )
local JSON = require ( " JSON " )
local OffsetDateTime = require ( " OffsetDateTime " )
local Math = require ( " Math " )
local Logger = require ( " Logger " )
-- Get the latest device data
local temperature = getLatestDataValue ( " device1.temperature " )
local humidity = getLatestDataValue ( " device1.humidity " )
Logger . infof ( " 当前温度: %.1f°C, 湿度: %.1f%% " , temperature , humidity )
-- Evaluate temperature alarm
local alarm = buildCommonAlarmMap ( " TEMP_HIGH " , " 温度超过80°C " )
Logger . error ( " 温度告警: " .. JSON . toJSONString ( alarm ))
local now = OffsetDateTime . now ()
local startTime = now : addHours ( - 24 )
local history = getHistoryData (
Logger . infof ( " 获取到 %d 条历史数据 " , # history )
for i , record in ipairs ( history ) do
local avg = sum / # history
Logger . infof ( " 24小时平均温度: %.2f°C " , Math . round ( avg * 100 ) / 100 )
local JSON = require ( " JSON " )
local Regex = require ( " Regex " )
local TableUtils = require ( " TableUtils " )
local String = require ( " String " )
local Logger = require ( " Logger " )
-- Get configuration from cache
local configJson = getShareCache ( " device_config " )
local config = JSON . decode ( configJson )
-- Filter enabled devices
local enabledDevices = TableUtils . filter ( config .devices, function ( device , index )
return device .enabled == true
local deviceNames = TableUtils . map ( enabledDevices , function ( device , index )
local cleanedNames = TableUtils . map ( deviceNames , function ( name , index )
-- Trim whitespace and convert to uppercase
return String . upper ( String . trim ( name ))
-- Validate device ID format
for i , device in ipairs ( enabledDevices ) do
if not Regex . match ( device .id, " ^DEV \\ d{6}$ " ) then
Logger . warnf ( " 设备编号格式错误: %s " , device .id)
Logger . info ( " 处理完成: " .. JSON . toJSONString ( cleanedNames ))
Error handling : most functions return (result, error); check errors when using them.
Time format : time strings use ISO 8601.
Regular expressions : use Go regular-expression syntax, which differs from native Lua patterns.
Table traversal : TableUtils map/filter/reduce traverse the array portion (1..n) first, then key/value pairs.
Log level : system configuration determines Logger output levels.
JSON performance : the runtime uses high-performance JSON processing suited to bulk serialization.
if isNotNull (${ some_key }) then
return { buildCommonWriteMap ( " Collection " , " target_key " , ${ some_key }, nil , nil , false ) }