- Visão geral do Jelina
- EMS Builder
- Manual de referência
Manual de scripts de publicação/assinatura MQTT
A sintaxe dos scripts é Lua. Para os conceitos gerais de MQTT e as funções das configurações de conexão, publicação e assinatura, leia primeiro Colaboração entre nuvem e borda por MQTT. Esta página detalha os parâmetros de gravação, exemplos completos de scripts e formatos das mensagens de solicitação e resposta.
Visão geral
Seção intitulada “Visão geral”- É possível personalizar o formato de publicação dos dados MQTT e configurar tarefas CRON para envio dos dados.
- É possível personalizar a interpretação das mensagens recebidas em tópicos assinados; o backend do Edge-EMS Builder grava nos pontos especificados conforme o resultado interpretado.
- É possível definir se o processamento de uma mensagem recebida em um tópico assinado exige response, além de seu topic e conteúdo.
Observação: o usuário precisa de conhecimentos básicos de programação e familiaridade com publicação e assinatura MQTT. Para a sintaxe dos scripts, consulte a Referência completa de scripts Lua.
Se não houver valor para um ponto referenciado no script, será inserida a string sentinela
__Null__. Verifique explicitamente${dataKey} == "__Null__"; não presuma que seja uma string vazia ounil.
Conexão MQTT
Seção intitulada “Conexão MQTT”| Nome do parâmetro | Valor | Obrigatório? | Tipo | Descrição |
|---|---|---|---|---|
| mqttConnectionConfigName | Nome da configuração de conexão | Sim | String | Nome da configuração de conexão MQTT |
| status | Valid | Sim | String | Estado: indica se a conexão está habilitada |
| protocol | mqtts | Sim | String | Protocolo MQTT, com suporte a mqtt/mqtts |
| protocolVersion | 3.1.1 | Sim | String | Versão do protocolo MQTT: 3.1/3.1.1/5.0 |
| serverHost | 127.0.0.1 | Sim | String | Endereço de conexão MQTT |
| serverPort | 8883 | Sim | String | Porta de conexão MQTT |
| clientId | return "demo-edge" |
Sim | String | Expressão Lua que retorna o ID do cliente |
| username | username | Sim | String | Nome de usuário |
| password | password | Sim | String | Senha |
| cleanSession | true | Sim | Boolean | Limpeza de sessão |
| sessionExpiryInterval | 0 | Sim | Number | Intervalo de expiração da sessão, exclusivo do MQTT5.0 |
| keepAliveInterval | 60 | Sim | String | Intervalo de heartbeat |
| connectTimeout | 30 | Sim | String | Tempo limite de conexão |
| sslEnable | true | Sim | Boolean | Define se SSL é usado |
Publicação de dados MQTT
Seção intitulada “Publicação de dados MQTT”| Nome do parâmetro | Valor | Obrigatório? | Tipo | Descrição |
|---|---|---|---|---|
| mqttConnectionConfigId | 100101 | Sim | Number | ID da configuração de conexão MQTT |
| mqttPublishConfigName | Nome da configuração de publicação | Sim | String | Nome da configuração de publicação MQTT |
| topic | return "demo/telemetry" |
Sim | String | Expressão Lua que retorna o tópico |
| qos | “1” | Sim | String | Enumeração de QoS em string |
| publishStrategy | 0/10 * * * * ? | Sim | String | Estratégia de publicação, expressão CRON |
| publishContent | {“name”: “dataKey”} | Sim | String | Conteúdo da publicação, script Lua |
| note | note | Sim | String | Observações |
O fluxo de publicação serializa o resultado do script em JSON. Ao publicar um objeto, retorne diretamente uma table Lua; chamar toJsonString antes disso gera uma string JSON entre aspas.
Exemplo 1 de publishContent: construção de Table
Seção intitulada “Exemplo 1 de publishContent: construção de Table”local map = {}-- Data e horamap.time = OffsetDateTime.now():unixMilli()-- Valor de dado comummap.name = "${数据8}"-- Array de stringsmap.strList = { "${数据3}", "${数据4}" }-- Array de númeroslocal d3 = ${数据3}local d4 = ${数据4}map.numberList = { d3, d4 }
return mapExemplo 2 de publishContent: concatenação de strings
Seção intitulada “Exemplo 2 de publishContent: concatenação de strings”local json = '{"strList":["${数据3}","${数据4}"],"name":"${数据8}","time":' .. OffsetDateTime.now():unixMilli() .. ',"numberList":[' .. ${数据3} .. ',' .. ${数据4} .. ']}'return jsonToMap(json)Resultado da interpretação
Seção intitulada “Resultado da interpretação”{ "strList": [ "3.6", "0.6" ], "name": "2", "time": 1742180870064, "numberList": [ 3.6, 0.6 ]}Assinatura de mensagens MQTT
Seção intitulada “Assinatura de mensagens MQTT”| Nome do parâmetro | Valor | Obrigatório? | Tipo | Descrição |
|---|---|---|---|---|
| mqttConnectionConfigId | 2 | Sim | Number | ID da configuração de conexão MQTT |
| mqttSubscribeConfigName | Nome da configuração de assinatura | Sim | String | Nome da configuração de assinatura MQTT |
| status | Valid | Sim | String | Estado |
| topic | return "demo/commands" |
Sim | String | Expressão Lua que retorna o tópico |
| qos | “1” | Sim | String | Enumeração de QoS em string |
| actionContent | {} | Sim | String | Conteúdo da ação, script Lua |
| needResponse | true | Sim | Boolean | Define se response é necessário |
| responseTopic | return "demo/replies" |
Quando a resposta está habilitada | String | Expressão Lua que retorna o tópico de resposta |
| response | return {ok=true} |
Quando a resposta está habilitada | String | Script de resposta: strings são enviadas sem alteração, e table é serializada em JSON |
| note | note | Sim | String | Observações |
actionContent: interpretar a message recebida pela assinatura
Seção intitulada “actionContent: interpretar a message recebida pela assinatura”Parâmetros de gravação
Seção intitulada “Parâmetros de gravação”| Nome do parâmetro | Valor | Obrigatório? | Tipo | Descrição |
|---|---|---|---|---|
| dataType | Customization | Sim | String | Tipo dos dados a operar: Customization/Collection/Aggregation |
| dataKey | 功率 | Sim | String | dataKey exclusivo dos dados |
| dataValue | topic | Sim | String | Valor dos dados |
| availableDate | 2023-01-15T07:00:00+08:00 | Não | String | Data de início da vigência, Customization |
| expiredDate | 2023-01-15T10:00:00+08:00 | Não | String | Data de expiração, Customization |
Parâmetro fixo:
${subscribe_message}: message recebida pela assinatura do topic
Ao usar o Edge-EMS Builder, não configure um dataKey que coincida com os dataKey fixos definidos acima.
Interpretação de actionContent
Seção intitulada “Interpretação de actionContent”local messageMap = jsonToMap(${subscribe_message})local params = messageMap.paramslocal strategyList = jsonToListMap(toJsonString(params.strategy))local date = params.datelocal resultList = {}
for i, keyMap in ipairs(strategyList) do local availableDate = completeDateTime(date .. "T" .. keyMap.start) local expiredDate = completeDateTime(date .. "T" .. keyMap["end"])
-- Tipo dos dados a gravar: Collection (originais)/Customization (por faixa de horário)/Aggregation (agregados) local modeMap = buildCommonWriteMap("Customization", "mode", tostring(keyMap.mode), availableDate, expiredDate, false) local chargeMap = buildCommonWriteMap("Customization", "charge", tostring(keyMap.charge), availableDate, expiredDate, false) local valueMap = buildCommonWriteMap("Customization", "value", tostring(keyMap.value), availableDate, expiredDate, false)
table.insert(resultList, modeMap) table.insert(resultList, chargeMap) table.insert(resultList, valueMap)end
table.insert(resultList, buildSlaveWriteMap("DeviceB", "Share", "数据4", 777, nil, nil, false))
return resultListExemplo de solicitação
Seção intitulada “Exemplo de solicitação”/rpc/${iot_code}/${method}/request
Topic assinado: /rpc/yanhua001/ems/strategy/request
Observação: iot_code é um dado agregado.
Enviar mensagem
Seção intitulada “Enviar mensagem”{ "jsonrpc":"2.0", "id":"d1acc980-0e4e-11e8-98f0-ab5030b47df4:d1db7aa0-0e4e-11e8-b1d9-5f0ab230c0d9", "method":"ems/strategy", "params":{ "date":"2023-1-15", "strategy":[ { "strategyDate":"2023-1-15", "start":"00:00:00", "end":"05:00:00", "mode":1, "charge":true, "value":100 }, { "start":"05:00:00", "end":"07:00:00", "mode":2, "charge":false, "value":100 } ] } }Resultado da interpretação de action
Seção intitulada “Resultado da interpretação de action”Requisitos do resultado interpretado:
- dataType deve ser Collection (dados originais), Customization (dados por faixa de horário) ou Aggregation (dados agregados).
- dataKey deve existir.
- Se o mesmo dataKey de Customization tiver vários value, os intervalos de vigência de cada value não podem se sobrepor.
- Ao atualizar dados Customization, os existentes são completamente removidos e substituídos pelos enviados nesta operação.
{ "actionType": "SUBSCRIBE", "actionResult": true, "mqttActionContent": { "Customization": { "mode": [ { "dataType": "Customization", "dataKey": "mode", "dataValue": "1", "availableDate": "2023-01-15T00:00:00+08:00", "expiredDate": "2023-01-15T05:00:00+08:00" }, { "dataType": "Customization", "dataKey": "mode", "dataValue": "2", "availableDate": "2023-01-15T05:00:00+08:00", "expiredDate": "2023-01-15T07:00:00+08:00" } ], "charge": [ { "dataType": "Customization", "dataKey": "charge", "dataValue": "true", "availableDate": "2023-01-15T00:00:00+08:00", "expiredDate": "2023-01-15T05:00:00+08:00" }, { "dataType": "Customization", "dataKey": "charge", "dataValue": "false", "availableDate": "2023-01-15T05:00:00+08:00", "expiredDate": "2023-01-15T07:00:00+08:00" } ], "value": [ { "dataType": "Customization", "dataKey": "value", "dataValue": "100", "availableDate": "2023-01-15T00:00:00+08:00", "expiredDate": "2023-01-15T05:00:00+08:00" }, { "dataType": "Customization", "dataKey": "value", "dataValue": "100", "availableDate": "2023-01-15T05:00:00+08:00", "expiredDate": "2023-01-15T07:00:00+08:00" } ] } }, "mqttActionResult": {
}}responseTopic: interpretar a assinatura de response
Seção intitulada “responseTopic: interpretar a assinatura de response”Parâmetro fixo:
${subscribe_message}: message recebida pela assinatura do topic
${subscribe_result}: indica se actionContent foi executado com sucesso
${subscribe_result_message}: resultado da execução de actionContent, como no Resultado da interpretação de action
Ao usar o Edge-EMS Builder, não configure um dataKey que coincida com os dataKey fixos definidos acima.
Interpretação de responseTopic
Seção intitulada “Interpretação de responseTopic”local messageMap = jsonToMap(${subscribe_message})local id = messageMap.idlocal method = messageMap.methodreturn "/rpc/" .. "${iot_code}" .. "/" .. method .. "/response/" .. idExemplo de solicitação
Seção intitulada “Exemplo de solicitação”/rpc/${iot_code}/${method}/response/${id}
Topic de destino da resposta: /rpc/yanhua001/ems/strategy/response/d1acc980-0e4e-11e8-98f0-ab5030b47df4:d1db7aa0-0e4e-11e8-b1d9-5f0ab230c0d9
Enviar mensagem
Seção intitulada “Enviar mensagem”{ "jsonrpc":"2.0", "id":"d1acc980-0e4e-11e8-98f0-ab5030b47df4:d1db7aa0-0e4e-11e8-b1d9-5f0ab230c0d9", "method":"ems/strategy", "params":{ "date":"2023-1-15", "strategy":[ { "strategyDate":"2023-1-15", "start":"00:00:00", "end":"05:00:00", "mode":1, "charge":true, "value":100 }, { "start":"05:00:00", "end":"07:00:00", "mode":2, "charge":false, "value":100 } ] } }Resultado da interpretação do topic
Seção intitulada “Resultado da interpretação do topic”/rpc/yanhua001/ems/strategy/response/d1acc980-0e4e-11e8-98f0-ab5030b47df4:d1db7aa0-0e4e-11e8-b1d9-5f0ab230c0d9response: montar a resposta de retorno
Seção intitulada “response: montar a resposta de retorno”Interpretação de response
Seção intitulada “Interpretação de response”local messageMap = jsonToMap(${subscribe_message})local id = messageMap.idlocal jsonrpc = messageMap.jsonrpclocal result = "${subscribe_result}"
local resultMap = {}resultMap.jsonrpc = jsonrpcresultMap.result = resultresultMap.id = id
return resultMapExemplo de solicitação
Seção intitulada “Exemplo de solicitação”/rpc/${iot_code}/${method}/response/${id}
Topic de destino da resposta: /rpc/yanhua001/ems/strategy/response/d1acc980-0e4e-11e8-98f0-ab5030b47df4:d1db7aa0-0e4e-11e8-b1d9-5f0ab230c0d9
Enviar mensagem
Seção intitulada “Enviar mensagem”{ "jsonrpc":"2.0", "id":"d1acc980-0e4e-11e8-98f0-ab5030b47df4:d1db7aa0-0e4e-11e8-b1d9-5f0ab230c0d9", "method":"ems/strategy", "params":{ "date":"2023-1-15", "strategy":[ { "strategyDate":"2023-1-15", "start":"00:00:00", "end":"05:00:00", "mode":1, "charge":true, "value":100 }, { "start":"05:00:00", "end":"07:00:00", "mode":2, "charge":false, "value":100 } ] } }Resultado da interpretação do topic
Seção intitulada “Resultado da interpretação do topic”Observação: na transmissão real, o JSON é compactado.
{ "result": "true", "id": "d1acc980-0e4e-11e8-98f0-ab5030b47df4:d1db7aa0-0e4e-11e8-b1d9-5f0ab230c0d9", "jsonrpc": "2.0"}Próximos passos
Seção intitulada “Próximos passos”- Conceitos gerais de conexão, publicação, assinatura e retomada após desconexão: Colaboração entre nuvem e borda por MQTT.
- Referência completa das funções e módulos Lua integrados: Referência completa de scripts Lua.