Ir al contenido
JelinaJelina DocumentationDocumentación técnica
Volver al sitio oficial

Referencia completa de scripts Lua

Este manual documenta las capacidades de scripting del motor de expresiones de Edge-EMS Builder: agregaciones, condiciones y acciones de disparadores, posprocesamiento y contenido de publicación y suscripción MQTT. La sintaxis es Lua 5.x, interpretada por el entorno Lua incorporado. Para comenzar, consulta Motor de expresiones. Aquí se detallan módulos, firmas de funciones globales y convenciones de retorno.

⚠️ Si utilizaste las primeras versiones Java de Edge-EMS Builder, con QLExpress4 y sintaxis similar a Java, ten en cuenta que los marcadores ${...} se mantienen en gran medida, pero el cuerpo del script utiliza ahora Lua estándar: new ArrayList() pasa a {}, .add(x) a table.insert(t, x), new HashMap() a {} y .put(k, v) a t[k] = v. La mayoría de nombres de funciones incorporadas se conservan; utiliza esta referencia para migrar.

  • Lenguaje: Lua 5.x; nombres de funciones y marcadores distinguen mayúsculas de minúsculas.
  • Marcadores de datos: el motor sustituye ${dataKey} por el valor actual antes de ejecutar. Para otros dispositivos, utiliza ${[deviceCode]dataKey}.
  • Valor centinela: si no hay datos, se inserta __Null__ como cadena. Compárala explícitamente o utiliza isNull / isNotNull; convierte primero con tonumber para cálculos numéricos.
  • El retorno depende del escenario, como se detalla más adelante. Un tipo de retorno incorrecto es una de las causas más frecuentes de errores de configuración.
  • Las funciones de módulos requieren require("nombreDelMódulo"); las funciones globales, como buildCommonWriteMap y jsonToMap, se invocan directamente.
  • Registros: el nivel predeterminado de Logger es WARN. Solo Logger.warn() y Logger.error() generan salida; no utilices únicamente Logger.info() o Logger.debug() para depurar.

1. Análisis de datos: referencias a variables

Sección titulada «1. Análisis de datos: referencias a variables»
Sintaxis Descripción
${variable} Devuelve el valor actual
${variable[-1s]} Devuelve el valor de hace un segundo
${variable[-5s]} Devuelve el valor de hace 5 segundos
${variable[raw]} Inserta el valor literal sin conversión automática de tipo. Para datos ambiguos, como el número 1000 y el binario 1000, utiliza raw para controlar la inserción literal. [raw] solo puede y debe situarse al final.
${[deviceA]variable} Devuelve el valor del dispositivo compartido deviceA
${variable[@timestamp]} Devuelve el valor en un instante absoluto indicado
${variable[#N]} Devuelve el enésimo valor histórico contando desde el más reciente; sin esta regla, devuelve el último valor
${[deviceA]variable[-5s][#N]} Devuelve la enésima muestra anterior al instante de hace 5 segundos del dispositivo compartido deviceA

Si un punto no tiene valor, el motor inserta siempre __Null__. Compruébalo explícitamente, por ejemplo: if ${some_key} == "__Null__" then ... end.

2. Convenciones de retorno según el escenario

Sección titulada «2. Convenciones de retorno según el escenario»

Cada ubicación de script exige un retorno distinto. Esta diferencia es una fuente habitual de errores:

Escenario Ubicación de configuración Retorno requerido
Condición de disparo Expresión de condición Un booleano (true indica que se cumple la condición)
Acción de disparador en esquemas de expresiones Contenido de la acción (Expression) Tabla de array con índices consecutivos desde 1, cuyos elementos son mapas devueltos por buildCommonWriteMap(...) u otras funciones; {} significa que no hay escrituras
Acción de disparador en esquemas de escritura mixta Acción vinculada individualmente a cada dataKey Un valor único, cadena, número o booleano, que se escribe en ese dataKey; no devuelvas un array de buildCommonWriteMap
Acción de posprocesamiento Script de finalización tras ejecutar la acción del disparador Igual que una acción de expresiones: array de descriptores de escritura. ${trigger_result} (booleano) y ${trigger_write_result} (cadena JSON que requiere jsonToMap) permiten evaluar el resultado principal
Expresión de un punto agregado Expresión de cálculo de datos agregados Un valor único, como número o cadena, que se convierte en el valor más reciente del punto
Contenido de publicación MQTT (publishContent) Configuración de publicación MQTT Tabla Lua, serializada como JSON para la carga útil de publicación
Acción de suscripción MQTT (actionContent) Configuración de suscripción MQTT Igual que una acción de expresiones: array de descriptores de escritura
Topic de respuesta MQTT (responseTopic) Configuración de suscripción MQTT Una cadena que se utiliza como topic de publicación de la respuesta
Contenido de respuesta MQTT (response) Configuración de suscripción MQTT Las cadenas se envían literalmente; los demás valores, como tablas Lua, se serializan como JSON

Cada invocación tiene un tiempo máximo de ejecución, 10 segundos de forma predeterminada. Superarlo hace fallar la ejecución. Evita consultas históricas o solicitudes HTTP sin límites dentro de bucles.

Los siguientes módulos requieren primero require("nombreDelMódulo"):

Módulo completo de fecha y hora, con zonas horarias, formato y cálculos.

local OffsetDateTime = require("OffsetDateTime")
Método Descripción Retorno
new() Crea la fecha y hora actuales OffsetDateTime
new(sec, nsec?) Crea a partir de una marca de tiempo Unix OffsetDateTime
now() Obtiene la fecha y hora actuales OffsetDateTime
parse(str) Analiza una cadena de fecha y hora OffsetDateTime | (nil, err)
parseInLocation(str, location) Analiza una fecha y hora en la zona indicada OffsetDateTime | (nil, err)
unix(sec, nsec?) Crea a partir de segundos Unix OffsetDateTime
unixMilli(msec) Crea a partir de una marca de tiempo en milisegundos OffsetDateTime
unixMicro(usec) Crea a partir de una marca de tiempo en microsegundos OffsetDateTime

Métodos de instancia: componentes temporales

Sección titulada «Métodos de instancia: componentes temporales»
Método Descripción Retorno
year() Obtiene el año number
month() Obtiene el mes (1-12) number
day() Obtiene el día del mes (1-31) number
hour() Obtiene la hora (0-23) number
minute() Obtiene los minutos (0-59) number
second() Obtiene los segundos (0-59) number
nanosecond() Obtiene los nanosegundos number
yearDay() Obtiene el día del año number
weekday() Obtiene el día de la semana (0 = domingo) number
isoWeek() Obtiene la información de semana ISO {year, week}
date() Obtiene año, mes y día {year, month, day}
clock() Obtiene horas, minutos y segundos {hour, minute, second}
Método Descripción Retorno
add(durationStr) Añade una duración OffsetDateTime | (nil, err)
addDate(years, months, days) Añade años, meses y días OffsetDateTime
sub(other) Calcula la diferencia temporal en nanosegundos number
addYears(n) Añade años OffsetDateTime
addMonths(n) Añade meses OffsetDateTime
addDays(n) Añade días OffsetDateTime
addHours(n) Añade horas OffsetDateTime
addMinutes(n) Añade minutos OffsetDateTime
addSeconds(n) Añade segundos OffsetDateTime
addMilliseconds(n) Añade milisegundos OffsetDateTime
addMicroseconds(n) Añade microsegundos OffsetDateTime
addNanoseconds(n) Añade nanosegundos OffsetDateTime

Métodos de instancia: diferencias temporales

Sección titulada «Métodos de instancia: diferencias temporales»
Método Descripción Retorno
diffYears(other) Calcula la diferencia en años number
diffMonths(other) Calcula la diferencia en meses number
diffDays(other) Calcula la diferencia en días number
diffHours(other) Calcula la diferencia en horas number
diffMinutes(other) Calcula la diferencia en minutos number
diffSeconds(other) Calcula la diferencia en segundos number

Métodos de instancia: comparación temporal

Sección titulada «Métodos de instancia: comparación temporal»
Método Descripción Retorno
equal(other) Comprueba la igualdad boolean
before(other) Comprueba si es anterior boolean
after(other) Comprueba si es posterior boolean
isZero() Comprueba si es el valor cero boolean

Métodos de instancia: comprobaciones temporales

Sección titulada «Métodos de instancia: comprobaciones temporales»
Método Descripción Retorno
isToday() Comprueba si es hoy boolean
isYesterday() Comprueba si es ayer boolean
isTomorrow() Comprueba si es mañana boolean
isThisWeek() Comprueba si pertenece a esta semana boolean
isThisMonth() Comprueba si pertenece a este mes boolean
isThisYear() Comprueba si pertenece a este año boolean
isBetween(start, end) Comprueba si está dentro del intervalo boolean
isInRange(start, end) Comprueba si está dentro del intervalo boolean
Método Descripción Retorno
format(layout) Aplica un formato personalizado string
toString() Convierte a cadena string
toDateTimeString() Formato de fecha y hora string
toDateString() Formato de fecha string
toTimeString() Formato de hora string
toYearString() Año string
toMonthString() Mes string
toDayString() Día string
toHourString() Hora string
toMinuteString() Minuto string
toSecondString() Segundo string

Métodos de instancia: marcas de tiempo Unix

Sección titulada «Métodos de instancia: marcas de tiempo Unix»
Método Descripción Retorno
unix() Marca de tiempo Unix en segundos number
unixMilli() Marca de tiempo Unix en milisegundos number
unixMicro() Marca de tiempo Unix en microsegundos number
unixNano() Marca de tiempo Unix en nanosegundos number
Método Descripción Retorno
utc() Convierte a UTC OffsetDateTime
local() Convierte a la zona horaria local OffsetDateTime
in(location) Convierte a la zona horaria indicada OffsetDateTime | (nil, err)
Método Descripción Retorno
truncate(durationStr) Trunca a la precisión indicada OffsetDateTime | (nil, err)
round(durationStr) Redondea a la precisión indicada OffsetDateTime | (nil, err)
toTime() Convierte a time.Time de Go 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")
-- Obtener la fecha y hora actuales
local now = OffsetDateTime.now()
Logger.warn(now:toString())
-- Analizar fecha y hora
local dt = OffsetDateTime.parse("2024-01-15T10:30:00.000Z")
Logger.warn("年份: " .. dt:year())
Logger.warn("月份: " .. dt:month())
-- Cálculos temporales
local tomorrow = now:addDays(1)
local nextWeek = now:addDays(7)
Logger.warn("明天: " .. tomorrow:toDateString())
-- Comparar fechas y horas
if now:isToday() then
Logger.warn("今天!")
end
-- Diferencia temporal
local hours = nextWeek:diffHours(now)
Logger.warn("相差小时: " .. hours)
-- Formato
Logger.warn(now:format("2006-01-02 15:04:05"))
Logger.warn(now:toDateTimeString())

Tipo que solo contiene horas, minutos y segundos, sin fecha ni zona horaria.

local LocalTime = require("LocalTime")
Método Descripción Retorno
new(hour, minute, second) Crea una hora LocalTime | (nil, err)
now() Obtiene la fecha y hora actuales LocalTime
parse(str) Analiza “HH:mm:ss” LocalTime | (nil, err)
fromTime(time.Time) Crea a partir de time.Time LocalTime | (nil, err)
fromDuration(durationStr) Crea a partir de una duración LocalTime | (nil, err)
Método Descripción Retorno
hour() Obtiene la hora number
minute() Obtiene los minutos number
second() Obtiene los segundos number
toString() Convierte a “HH:mm:ss” string
toDuration() Convierte a una cadena de duración string
equal(other) Comprueba la igualdad boolean
before(other) Comprueba si es anterior boolean
after(other) Comprueba si es posterior boolean
beforeOrEqual(other) Comprueba si es anterior o igual boolean
afterOrEqual(other) Comprueba si es posterior o igual boolean
isZero() Comprueba si es 00:00:00 boolean
diffSeconds(other) Diferencia en segundos number
diffMinutes(other) Diferencia en minutos number
diffHours(other) Diferencia en horas number
addSeconds(n) Añade segundos LocalTime
addMinutes(n) Añade minutos LocalTime
addHours(n) Añade horas LocalTime
subSeconds(n) Resta segundos LocalTime
subMinutes(n) Resta minutos LocalTime
subHours(n) Resta horas LocalTime
local LocalTime = require("LocalTime")
local Logger = require("Logger")
-- Crear una hora
local workStart = LocalTime.new(9, 0, 0) -- 09:00:00
local workEnd = LocalTime.new(17, 30, 0) -- 17:30:00
-- Obtener la fecha y hora actuales
local now = LocalTime.now()
Logger.warn("当前时间: " .. now:toString())
-- Comparar fechas y horas
if now:isBetween(workStart, workEnd) then
Logger.warn("工作时间")
else
Logger.warn("非工作时间")
end
-- Cálculos temporales
local breakTime = workStart:addHours(3):addMinutes(30) -- 12:30:00
Logger.warn("午休时间: " .. breakTime:toString())
-- Diferencia temporal
local workHours = workEnd:diffHours(workStart)
Logger.warn("工作时长: " .. workHours .. " 小时")

Salida de registros integrada con los registros del sistema.

local Logger = require("Logger")
Método Descripción Parámetros
info(msg) Emite un registro INFO string
warn(msg) Emite un registro WARN string
error(msg) Emite un registro ERROR string
debug(msg) Emite un registro DEBUG string
infof(fmt, ...) Emite un registro INFO con formato string, …
warnf(fmt, ...) Emite un registro WARN con formato string, …
errorf(fmt, ...) Emite un registro ERROR con formato string, …
debugf(fmt, ...) Emite un registro DEBUG con formato string, …
local Logger = require("Logger")
Logger.info("系统启动")
Logger.warn("磁盘空间不足")
Logger.error("数据库连接失败")
Logger.debug("变量值: x=10")
-- Salida con formato
local user = "admin"
local action = "login"
Logger.infof("用户 %s 执行操作: %s", user, action)
Logger.warnf("重试次数: %s", 3)

Nota: el nivel predeterminado de Edge-EMS Builder es WARN; solo se muestran registros WARN y ERROR.


Serialización, deserialización y manipulación de JSON, basado en bytedance/sonic.

local JSON = require("JSON")
Método Descripción Retorno
encode(value) Serializa como JSON string | (nil, err)
decode(text) Deserializa table | (nil, err)
Método Descripción Retorno
toJSONString(value) Serializa sin devolver error string
toJSONStringIndent(value, prefix?, indent?) Serializa con formato string
toMap(jsonStr) Convierte a map table | (nil, err)
toStringMap(jsonStr) Convierte a string map table | (nil, err)
toSlice(jsonStr) Convierte a array table | (nil, err)
isValid(jsonStr) Valida el formato JSON boolean
pretty(jsonStr) Aplica formato legible a JSON string
merge(json1, json2) Combina dos JSON string | (nil, err)
get(jsonStr, key) Obtiene un valor any | (nil, err)
set(jsonStr, key, value) Establece un valor string | (nil, err)
remove(jsonStr, key) Elimina una clave string | (nil, err)
clone(value) Realiza una copia profunda any | (nil, err)
local JSON = require("JSON")
local Logger = require("Logger")
-- Serialización y deserialización básicas
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)
if not decoded then
Logger.warn("解析失败: " .. err)
else
Logger.warn("姓名: " .. decoded.name)
end
-- Salida con formato
local pretty = JSON.pretty(jsonStr)
Logger.warn(pretty)
-- Validar JSON
if JSON.isValid(jsonStr) then
Logger.warn("有效的 JSON")
end
-- Manipular JSON
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":"北京"}
-- Combinar JSON
local json1 = '{"a":1}'
local json2 = '{"b":2}'
local merged = JSON.merge(json1, json2)
Logger.warn(merged) -- {"a":1,"b":2}
-- Copia profunda
local original = {data = {x = 10}}
local copied = JSON.clone(original)

Expresiones regulares para coincidencia, búsqueda, sustitución y división.

local Regex = require("Regex")
Método Descripción Retorno
match(text, pattern) Comprueba si hay coincidencia boolean
findAll(text, pattern, limit?) Busca todas las coincidencias, incluidos los grupos de captura {{full, g1, g2, …}, …} | (nil, err)
replace(text, pattern, repl) Sustituye; admite referencias de grupo como $1 string | (nil, err)
split(text, pattern, limit?) Divide mediante expresión regular {string, …} | (nil, err)
isEmail(text) Comprueba si es un correo electrónico boolean
isPhone(text) Comprueba si es un número de móvil de China boolean
isIP(text) Comprueba si es una dirección IP boolean
isURL(text) Comprueba si es una URL boolean
local Regex = require("Regex")
local Logger = require("Logger")
-- Coincidencia
if Regex.match("abc123", "\\d+") then
Logger.warn("包含数字")
end
-- Buscar todas las coincidencias, incluidos grupos de captura
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])
end
-- Sustituir, con referencias a grupos
local s = Regex.replace("abc-123-def", "(\\d+)", "[$1]")
Logger.warn(s) -- "abc-[123]-def"
-- Dividir
local parts = Regex.split("a,b,,c", ",", -1)
-- parts = {"a", "b", "", "c"}
for i, p in ipairs(parts) do
Logger.warn("部分 " .. i .. ": '" .. p .. "'")
end
-- Validar
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

Utilidades de procesamiento de cadenas.

local String = require("String")
Método Descripción Retorno
trim(s) Elimina espacios en blanco iniciales y finales string
upper(s) Convierte a mayúsculas string
lower(s) Convierte a minúsculas string
contains(s, sub) Comprueba si contiene una subcadena boolean
startsWith(s, prefix) Comprueba si comienza por el prefijo indicado boolean
endsWith(s, suffix) Comprueba si termina en el sufijo indicado 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

Utilidades de cálculo matemático.

local Math = require("Math")
Método Descripción Retorno
round(n) Redondea al entero más próximo number
floor(n) Redondea hacia abajo number
ceil(n) Redondea hacia arriba number
abs(n) Valor absoluto number
max(a, b) Máximo number
min(a, b) Mínimo 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

Utilidades para tablas, con recorrido de arrays y pares clave-valor.

local TableUtils = require("TableUtils")
Método Descripción Retorno
keys(tbl) Obtiene todas las claves {string, …}
values(tbl) Obtiene todos los valores {any, …}
map(tbl, fn) Transforma mediante fn(value, key) {any, …}
filter(tbl, fn) Filtra mediante fn(value, key) {any, …}
reduce(tbl, fn, init) Reduce mediante fn(acc, value, key) any
sortBy(tblOfMaps, key) Ordena por clave de forma estable {map, …}
local T = require("TableUtils")
-- keys/values
local obj = {a = 1, b = 2, c = 3}
local keys = T.keys(obj) -- {"a", "b", "c"}
local values = T.values(obj) -- {1, 2, 3}
-- map: array
local arr = {1, 2, 3}
local doubled = T.map(arr, function(v, i)
return v * 2
end)
-- doubled = {2, 4, 6}
-- map: pares clave-valor
local mapped = T.map({a=1, b=2}, function(v, k)
return k .. ":" .. v
end)
-- mapped = {"a:1", "b:2"}
-- filter
local arr = {1, 2, 3, 4, 5}
local even = T.filter(arr, function(v, i)
return v % 2 == 0
end)
-- even = {2, 4}
-- reduce
local sum = T.reduce({1, 2, 3}, function(acc, v, i)
return acc + v
end, 0)
-- sum = 6
-- sortBy
local users = {
{name="张三", age=30},
{name="李四", age=25},
{name="王五", age=35}
}
local sorted = T.sortBy(users, "age")
-- sorted = {{name="李四",age=25}, {name="张三",age=30}, {name="王五",age=35}}

Estas funciones se registran directamente en el ámbito global y no requieren require.

Función Finalidad
cp56Time2aToOffsetDateTime(hex[, byteOrder]) Decodifica una fecha y hora IEC 60870-5 y devuelve OffsetDateTime
offsetDateTimeToCP56Time2a(time[, byteOrder]) Codifica la fecha y hora como carga útil hexadecimal

byteOrder admite AB / BA; si se omite, utiliza AB estándar. Cuando se indica explícitamente, se admiten cargas útiles de cuatro registros. Si la posición del relleno con ceros es ambigua, se devuelve un error; comprueba la disposición de registros del dispositivo.

Función Descripción Retorno
jsonToMap(str) Convierte JSON a map table | (nil, err)
jsonToList(str) Convierte JSON a list table | (nil, err)
jsonToListMap(str) Convierte JSON a list of map table | (nil, err)
completeDateTime(str) Completa una cadena de fecha y hora string | (nil, err)
quoteJson(str) Escapa las comillas de JSON string
simpleUUID() Genera un UUID simple string
convertString(str) Convierte el tipo de una cadena any
isNull(any) Comprueba si el valor está vacío bool
isNotNull(any) Comprueba si el valor no está vacío bool

isNull considera vacíos nil, la cadena vacía, “null” sin distinguir mayúsculas y el centinela __Null__. or 0 de Lua no trata ese centinela.

local Logger = require("Logger")
-- Analizar JSON
local map, err = jsonToMap('{"a":1,"b":2}')
if map then
Logger.warn(map.a) -- 1
end
local list = jsonToList('[1,2,3]')
-- list = {1, 2, 3}
-- Completar fecha y hora
local fullTime = completeDateTime("2024-01-15")
-- fullTime = "2024-01-15T00:00:00.000+08:00"
-- Generar UUID
local id = simpleUUID()
Logger.warn(id) -- Cadena UUID de 32 caracteres

Función Descripción Retorno
getLatestDataValue(dataKey) Obtiene el valor de datos más reciente any
getAccountCache(key) Obtiene la caché de cuentas any
getEMSDataCache(key) Obtiene la caché de datos EMS any
getShareCache(key) Obtiene la caché de datos compartidos any
getMqttCache(key) Obtiene la caché MQTT any
getTriggerCache(key) Obtiene la caché de disparadores any
getDeviceShareValue(deviceCode, dataKey) Obtiene el último valor compartido de un dispositivo mediante un deviceCode y un dataKey string | nil
getDeviceShareValues(deviceCodes, dataKey) Obtiene el último valor de cada dispositivo mediante una lista de dispositivos y un dataKey table
getAllDeviceShareValues(dataKey) Obtiene el último valor de todos los dispositivos del espacio compartido para un dataKey table
local Logger = require("Logger")
-- Obtener los datos más recientes del dispositivo
local value = getLatestDataValue("device1.temperature")
Logger.warn("当前温度: " .. value)
-- Obtener información de la cuenta
local account = getAccountCache("user123")
if account then
Logger.warn("用户名: " .. account.username)
end
-- Obtener datos compartidos
local sharedData = getShareCache("shared_config")
-- Obtener el valor compartido más reciente de un dispositivo
local val = getDeviceShareValue("device1", "temperature")
if val ~= nil then
Logger.warn("设备 device1 温度: " .. val)
end
-- Obtener valores compartidos de cada dispositivo de una lista
local deviceCodes = {"device1", "device2"}
local shareValues = getDeviceShareValues(deviceCodes, "temperature")
if shareValues then
for deviceCode, dataValue in pairs(shareValues) do
Logger.warn("设备 " .. deviceCode .. " 温度: " .. dataValue)
end
end
-- Obtener valores compartidos de todos los dispositivos
local allShareValues = getAllDeviceShareValues("temperature")
if allShareValues then
for deviceCode, dataValue in pairs(allShareValues) do
Logger.warn("设备 " .. deviceCode .. " 温度: " .. dataValue)
end
end

Consultas por lotes de valores recientes mediante patrones de dataKey

Sección titulada «Consultas por lotes de valores recientes mediante patrones de dataKey»

Estas funciones recorren la caché local de valores recientes, filtran por prefijo, sufijo o palabra clave de dataKey y devuelven los puntos coincidentes como una tabla {dataKey: FrontDataDTO}.

Campos del retorno: cada valor es un FrontDataDTO con estos campos habituales:

Campo Tipo Descripción
DataKey string Clave única del dato
DataValue string Valor más reciente
DataType string Tipo de datos
DataName string Nombre del dato
DataUnit string Unidad
CollectionTime OffsetDateTime Hora de adquisición

Nota: nil indica que no hay coincidencias en la caché. dataType debe coincidir exactamente con Collection, Customization, Aggregation o Share.

Función Descripción Retorno
getLatestDataValuesBySuffix(dataType, suffix) Consulta los últimos valores del tipo indicado cuyo dataKey termina en suffix table | nil
getAllLatestDataValuesBySuffix(suffix) Consulta los últimos valores de todos los tipos cuyo dataKey termina en suffix table | nil
Función Descripción Retorno
getLatestDataValuesByPrefix(dataType, prefix) Consulta los últimos valores del tipo indicado cuyo dataKey empieza por prefix table | nil
getAllLatestDataValuesByPrefix(prefix) Consulta los últimos valores de todos los tipos cuyo dataKey empieza por prefix table | nil
Función Descripción Retorno
getLatestDataValuesByPrefixAndSuffix(dataType, prefix, suffix) Consulta los últimos valores del tipo indicado cuyo dataKey cumple prefix y suffix table | nil
getAllLatestDataValuesByPrefixAndSuffix(prefix, suffix) Consulta los últimos valores de todos los tipos cuyo dataKey cumple prefix y suffix table | nil

Búsqueda parcial: contiene la palabra clave

Sección titulada «Búsqueda parcial: contiene la palabra clave»
Función Descripción Retorno
getLatestDataValuesByFuzzy(dataType, keyword) Consulta los últimos valores del tipo indicado cuyo dataKey contiene keyword table | nil
getAllLatestDataValuesByFuzzy(keyword) Consulta los últimos valores de todos los tipos cuyo dataKey contiene keyword table | nil
local Logger = require("Logger")
-- Consultar los últimos valores adquiridos cuyas claves terminan en "_power"
local powerValues = getLatestDataValuesBySuffix("Collection", "_power")
if powerValues then
for dataKey, dto in pairs(powerValues) do
Logger.warn(dataKey .. " = " .. dto.DataValue)
end
end
-- Consultar los últimos valores que terminan en "_power" de todos los tipos
local allPower = getAllLatestDataValuesBySuffix("_power")
-- Consultar todos los datos adquiridos que empiezan por "meter1."
local meterValues = getLatestDataValuesByPrefix("Collection", "meter1.")
if meterValues then
for dataKey, dto in pairs(meterValues) do
Logger.warnf("%s = %s (%s)", dataKey, dto.DataValue, dto.DataUnit)
end
end
-- Consultar datos que empiezan por "meter1." de todos los tipos
local allMeter = getAllLatestDataValuesByPrefix("meter1.")
-- Consultar datos adquiridos cuyo dataKey empieza por "meter1." y termina en "_voltage"
local voltages = getLatestDataValuesByPrefixAndSuffix("Collection", "meter1.", "_voltage")
-- Consultar datos que cumplen prefix y suffix de todos los tipos
local allVoltages = getAllLatestDataValuesByPrefixAndSuffix("meter1.", "_voltage")
-- Búsqueda parcial: últimos valores agregados cuyo dataKey contiene "temp"
local tempValues = getLatestDataValuesByFuzzy("Aggregation", "temp")
if tempValues then
for dataKey, dto in pairs(tempValues) do
Logger.warn("温度点位: " .. dataKey .. " = " .. dto.DataValue)
end
end
-- Búsqueda parcial: últimos valores de todos los tipos cuyo dataKey contiene "temp"
local allTemp = getAllLatestDataValuesByFuzzy("temp")

Función Descripción Retorno
getDeviceList(ignoreLocal) Obtiene la lista de dispositivos; ignoreLocal=true excluye el equipo local table
getDeviceCodeList(ignoreLocal) Obtiene la lista de deviceCode; ignoreLocal=true excluye el equipo local table
local Logger = require("Logger")
-- Obtener la lista completa de dispositivos
local allDevices = getDeviceList(false)
if allDevices then
for i, device in ipairs(allDevices) do
Logger.warn("设备: " .. device.deviceCode .. " - " .. device.deviceName)
end
end
-- Obtener dispositivos excluyendo el equipo local
local otherDevices = getDeviceList(true)
if otherDevices then
for i, device in ipairs(otherDevices) do
Logger.warn("共享设备: " .. device.deviceCode)
end
end
-- Obtener todos los códigos de dispositivo, más rápido que la información completa
local deviceCodes = getDeviceCodeList(false)
if deviceCodes then
for i, code in ipairs(deviceCodes) do
Logger.warn("设备编码: " .. code)
end
end
-- Obtener códigos de dispositivo excluyendo el equipo local
local otherDeviceCodes = getDeviceCodeList(true)

Función Descripción Retorno
getHistoryData(dataType, dataKey, startTime?, endTime?, formatMap?) Obtiene datos históricos table
getShareHistoryData(deviceCode, dataKey, startTime?, endTime?, formatMap?) Obtiene históricos compartidos del dispositivo indicado table
getTimeData(dataKey, time?, interval?) Obtiene datos de un instante indicado table
getShareTimeData(deviceCode, dataKey, time?, interval?) Obtiene datos compartidos de un instante indicado table
deleteCustomizationData(dataKey, startTime?, endTime?) Elimina datos personalizados boolean

Parámetros:

  • startTime/endTime/time admite:
    • Un objeto OffsetDateTime, recomendado.
    • Una cadena temporal, como “2024-01-15T10:00:00.000Z”.
    • Una cadena abreviada, como “2024-01-15”, que se completa automáticamente.
  • formatMap es una tabla opcional para personalizar los nombres de campos del resultado:
    • dataKey: nombre del campo de clave; predeterminado “dataKey”.
    • dataValue: nombre del campo de valor; predeterminado “dataValue”.
    • collectionTime: nombre del campo de hora de adquisición; predeterminado “collectionTime”.

Campos temporales devueltos para Customization:

En getHistoryData / getTimeData, dependen del tipo de programación:

  • DailyChange: availableTime, fecha y hora completas ISO 8601, y expiredTime.
  • DailyRepeat: availableTime y expiredTime, ambos cadenas HH:mm:ss.
local OffsetDateTime = require("OffsetDateTime")
local Logger = require("Logger")
-- Método 1: utilizar objetos OffsetDateTime, recomendado
local now = OffsetDateTime.now()
local startTime = now:addDays(-7)
local endTime = now
local data = getHistoryData("Collection", "temperature", startTime, endTime)
-- Ampliación del método 1: personalizar campos devueltos mediante formatMap
local formatMap = {
dataKey = "key",
dataValue = "value",
collectionTime = "time"
}
local data = getHistoryData("Collection", "temperature", startTime, endTime, formatMap)
-- Método 2: utilizar cadenas de fecha y hora
local data = getHistoryData("Collection", "temperature", "2024-01-01T00:00:00.000Z", "2024-01-31T23:59:59.000Z")
-- Método 3: utilizar cadenas abreviadas, completadas automáticamente
local data = getHistoryData("Collection", "temperature", "2024-01-01", "2024-01-31")
-- Consultar históricos compartidos
local sharedData = getShareHistoryData("space1", "pressure", startTime, endTime)
-- Consultar datos de un instante indicado
local value = getTimeData("temperature", now, "5m")
-- Eliminar datos personalizados
local deleted = deleteCustomizationData("data1", startTime, endTime)
Logger.warn("删除成功: " .. tostring(deleted))

Función Descripción Retorno
buildCommonWriteMap(dataType, dataKey, dataValue, availableDate, expiredDate, changeMod) Construye un mapa de escritura general table
buildGeneralWriteMap(dataType, dataKey, dataValue, changeMod) Construye un mapa de escritura general simplificado, sin parámetros temporales table
buildCustomizationWriteMap(dataKey, dataValue, availableDate, expiredDate) Construye un mapa de escritura DailyChange, con dataType=Customization implícito table
buildDailyRepeatWriteMap(dataKey, dataValue, availableTime, expiredTime) Construye un mapa de escritura DailyRepeat, con dataType=Customization implícito y parámetros temporales como cadenas HH:mm:ss table
updateDailyRepeatSchedule(dataKey, scheduleAvailableDate, scheduleExpiredDate) Actualiza el intervalo global de vigencia de DailyRepeat; ambas fechas admiten nil, que indica ausencia de límite y vigencia permanente boolean
buildAlarmObservationMap(sourceCode, alarmKey, state, alarmType, alarmLevel, alarmContent[, detailKey]) Construye una observación de evento de alarma; state es ACTIVE / NORMAL / UNKNOWN table
buildCommonAlarmMap(alarmType, alarmContent) Construye un mapa de alarma general table
buildMqttAlarmMap(alarmType, alarmContent, mqttConnectionConfigId, topic, qos) Construye un mapa de alarma MQTT table
buildSlaveWriteMap(deviceCode, dataType, dataKey, dataValue, availableDate, expiredDate, changeMod) Construye un mapa de escritura en dispositivo subordinado table

Las observaciones de alarma utilizan una combinación estable de sourceCode + alarmKey. Envía NORMAL cuando el estado sea normal y UNKNOWN cuando falten datos o el dispositivo esté desconectado. El estado del evento es distinto del estado de observación; consulta Ciclo de vida de alarmas. Las funciones antiguas de construcción de alarmas siguen generando registros independientes.

CommBridge realiza la conversión inversa de coeficientes de escritura en puntos adquiridos. La función antigua buildCollectionWriteMap se ha eliminado; utiliza las funciones generales y no repitas la conversión.

Parámetros:

  • dataType: Collection (adquisición), Customization (personalizados/por franjas), Aggregation (agregados), Share (compartidos) o Alarm (alarmas).
  • availableDate / expiredDate: solo para Customization DailyChange; cadena ISO 8601 u objeto OffsetDateTime. Para otros tipos, utiliza nil.
  • availableTime / expiredTime: solo para Customization DailyRepeat; formato "HH:mm:ss", como "08:00:00", sin atravesar medianoche.
  • changeMod: booleano; true escribe únicamente si cambia el valor.
local OffsetDateTime = require("OffsetDateTime")
-- Escribir un punto adquirido
local writeCollection = buildCommonWriteMap("Collection", "temperature", 25.5, nil, nil, false)
-- Escribir un punto personalizado DailyChange con intervalo completo de fecha y hora
local writeCustom = buildCommonWriteMap(
"Customization", "mode", "1",
"2024-01-15T07:00:00+08:00",
"2024-01-15T18:00:00+08:00",
false
)
-- Escribir un punto personalizado DailyChange con su función abreviada
local writeCustom2 = buildCustomizationWriteMap(
"mode", "1",
"2024-01-15T07:00:00+08:00",
"2024-01-15T18:00:00+08:00"
)
-- Escribir un punto personalizado DailyRepeat con franjas diarias HH:mm:ss
local writeDailyRepeat = buildDailyRepeatWriteMap("charge_mode", "1", "08:00:00", "18:00:00")
-- Actualizar el intervalo global de vigencia de una configuración DailyRepeat
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"))
-- Establecer vigencia permanente pasando nil en ambas fechas
local ok2 = updateDailyRepeatSchedule("charge_mode", nil, nil)
-- Establecer inicio sin fin; nil significa que nunca caduca
local ok3 = updateDailyRepeatSchedule("charge_mode", "2026-01-01", nil)
-- Escribir un punto agregado: versión simplificada sin parámetros temporales
local writeAgg = buildGeneralWriteMap("Aggregation", "avg_temp", 22.5, false)
-- Construir una alarma para registrar localmente
local alarm = buildCommonAlarmMap("TEMP_HIGH", "温度超过80°C")
-- Construir una alarma MQTT, vinculando un ID de conexión y enviándola también al broker
local mqttAlarm = buildMqttAlarmMap("TEMP_HIGH", "温度超过80°C", 1, "alarm/upload", 1)
-- Escribir datos compartidos de un dispositivo subordinado
local slaveWrite = buildSlaveWriteMap("DeviceB", "Share", "shared_temp", 25.5, nil, nil, false)

Función Descripción Retorno
toFixedLengthBinary(value, length) Convierte a binario de longitud fija string | (nil, err)
toDecimal(binaryStr) Convierte binario a decimal number | (nil, err)
-- Convertir decimal a binario
local binary = toFixedLengthBinary(10, 8)
Logger.warn(binary) -- "00001010"
-- Convertir binario a 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")
Logger.info("设备监控脚本启动")
-- Obtener los datos más recientes del dispositivo
local temperature = getLatestDataValue("device1.temperature")
local humidity = getLatestDataValue("device1.humidity")
Logger.infof("当前温度: %.1f°C, 湿度: %.1f%%", temperature, humidity)
-- Evaluar alarma de temperatura
if temperature > 80 then
local alarm = buildCommonAlarmMap("TEMP_HIGH", "温度超过80°C")
Logger.error("温度告警: " .. JSON.toJSONString(alarm))
end
-- Consultar datos históricos
local now = OffsetDateTime.now()
local startTime = now:addHours(-24)
local history = getHistoryData(
"device1",
"temperature",
startTime:toString(),
now:toString()
)
Logger.infof("获取到 %d 条历史数据", #history)
-- Calcular la media
local sum = 0
for i, record in ipairs(history) do
sum = sum + record.value
end
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")
-- Obtener configuración de la caché
local configJson = getShareCache("device_config")
local config = JSON.decode(configJson)
-- Filtrar dispositivos habilitados
local enabledDevices = TableUtils.filter(config.devices, function(device, index)
return device.enabled == true
end)
-- Extraer nombres de dispositivos
local deviceNames = TableUtils.map(enabledDevices, function(device, index)
return device.name
end)
-- Limpiar datos
local cleanedNames = TableUtils.map(deviceNames, function(name, index)
-- Eliminar espacios y convertir a mayúsculas
return String.upper(String.trim(name))
end)
-- Validar formato del identificador de dispositivo
for i, device in ipairs(enabledDevices) do
if not Regex.match(device.id, "^DEV\\d{6}$") then
Logger.warnf("设备编号格式错误: %s", device.id)
end
end
-- Mostrar resultados
Logger.info("处理完成: " .. JSON.toJSONString(cleanedNames))

  1. Tratamiento de errores: la mayoría de funciones devuelven (result, error); comprueba el error.
  2. Formato temporal: utiliza cadenas ISO 8601.
  3. Expresiones regulares: utilizan sintaxis de Go, distinta de los patrones nativos de Lua.
  4. Recorrido de tablas: map/filter/reduce de TableUtils recorren primero la parte array, 1..n, y después los pares clave-valor.
  5. Nivel de registro: la configuración del sistema determina el nivel de Logger.
  6. Rendimiento JSON: el entorno utiliza procesamiento JSON de alto rendimiento, adecuado para serialización por lotes.
if isNotNull(${some_key}) then
return {}
end
return { buildCommonWriteMap("Collection", "target_key", ${some_key}, nil, nil, false) }