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.
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.
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é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é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é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é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é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 ())
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 ())
-- Comparar fechas y horas
local hours = nextWeek : diffHours ( now )
Logger . warn ( " 相差小时: " .. hours )
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 " )
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
local breakTime = workStart : addHours ( 3 ): addMinutes ( 30 ) -- 12:30:00
Logger . warn ( " 午休时间: " .. breakTime : toString ())
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 . debug ( " 变量值: x=10 " )
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 )
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 )
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 " )
if Regex . match ( " abc123 " , " \\ d+ " ) then
-- 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 ])
-- Sustituir, con referencias a grupos
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
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 " )
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 )
-- map: pares clave-valor
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}}
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 " )
local map , err = jsonToMap ( ' {"a":1,"b":2} ' )
local list = jsonToList ( ' [1,2,3] ' )
-- Completar fecha y hora
local fullTime = completeDateTime ( " 2024-01-15 " )
-- fullTime = "2024-01-15T00:00:00.000+08:00"
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 " )
Logger . warn ( " 用户名: " .. account .username)
-- Obtener datos compartidos
local sharedData = getShareCache ( " shared_config " )
-- Obtener el valor compartido más reciente de un dispositivo
local val = getDeviceShareValue ( " device1 " , " temperature " )
Logger . warn ( " 设备 device1 温度: " .. val )
-- Obtener valores compartidos de cada dispositivo de una lista
local deviceCodes = { " device1 " , " device2 " }
local shareValues = getDeviceShareValues ( deviceCodes , " temperature " )
for deviceCode , dataValue in pairs ( shareValues ) do
Logger . warn ( " 设备 " .. deviceCode .. " 温度: " .. dataValue )
-- Obtener valores compartidos de todos los dispositivos
local allShareValues = getAllDeviceShareValues ( " temperature " )
for deviceCode , dataValue in pairs ( allShareValues ) do
Logger . warn ( " 设备 " .. deviceCode .. " 温度: " .. dataValue )
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
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 " )
for dataKey , dto in pairs ( powerValues ) do
Logger . warn ( dataKey .. " = " .. dto .DataValue)
-- 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. " )
for dataKey , dto in pairs ( meterValues ) do
Logger . warnf ( " %s = %s (%s) " , dataKey , dto .DataValue, dto .DataUnit)
-- 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 " )
for dataKey , dto in pairs ( tempValues ) do
Logger . warn ( " 温度点位: " .. dataKey .. " = " .. dto .DataValue)
-- 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 )
for i , device in ipairs ( allDevices ) do
Logger . warn ( " 设备: " .. device .deviceCode .. " - " .. device .deviceName)
-- Obtener dispositivos excluyendo el equipo local
local otherDevices = getDeviceList ( true )
for i , device in ipairs ( otherDevices ) do
Logger . warn ( " 共享设备: " .. device .deviceCode)
-- Obtener todos los códigos de dispositivo, más rápido que la información completa
local deviceCodes = getDeviceCodeList ( false )
for i , code in ipairs ( deviceCodes ) do
Logger . warn ( " 设备编码: " .. code )
-- 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 data = getHistoryData ( " Collection " , " temperature " , startTime , endTime )
-- Ampliación del método 1: personalizar campos devueltos mediante formatMap
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 " ,
-- Escribir un punto personalizado DailyChange con su función abreviada
local writeCustom2 = buildCustomizationWriteMap (
" 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 " )
-- 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
local alarm = buildCommonAlarmMap ( " TEMP_HIGH " , " 温度超过80°C " )
Logger . error ( " 温度告警: " .. JSON . toJSONString ( alarm ))
-- Consultar datos históricos
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 " )
-- 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
-- Extraer nombres de dispositivos
local deviceNames = TableUtils . map ( enabledDevices , function ( device , index )
local cleanedNames = TableUtils . map ( deviceNames , function ( name , index )
-- Eliminar espacios y convertir a mayúsculas
return String . upper ( String . trim ( name ))
-- 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)
Logger . info ( " 处理完成: " .. JSON . toJSONString ( cleanedNames ))
Tratamiento de errores : la mayoría de funciones devuelven (result, error); comprueba el error.
Formato temporal : utiliza cadenas ISO 8601.
Expresiones regulares : utilizan sintaxis de Go, distinta de los patrones nativos de Lua.
Recorrido de tablas : map/filter/reduce de TableUtils recorren primero la parte array, 1..n, y después los pares clave-valor.
Nivel de registro : la configuración del sistema determina el nivel de Logger.
Rendimiento JSON : el entorno utiliza procesamiento JSON de alto rendimiento, adecuado para serialización por lotes.
if isNotNull (${ some_key }) then
return { buildCommonWriteMap ( " Collection " , " target_key " , ${ some_key }, nil , nil , false ) }