Cliente MQTT

O recurso de Cliente MQTT do HIscada Pro consiste, atualmente, em utilizar o objeto global chamado MqttClient via scripts do Kernel para gerenciar as ações de um cliente MQTT típico, como por exemplo:

  • Criar e remover conexões com um Broker MQTT;

  • Realizar publicações, assinaturas e remoção de assinaturas em tópicos, conforme parametrizado em cada Cliente MQTT.

ate

As funções de Cliente MQTT estão disponíveis a partir da versão 1.7.00 do HIscada Pro e devem ser utilizadas apenas em scripts do KERNEL.

Funções do gerenciador MqttClient

As atuais funções do gerenciador MtttClient são:

Função

Descrição

Connect

Cria um Cliente MQTT identificado por um nome e abre conexão com o Broker

Disconnect

Fecha a conexão do Cliente MQTT com o Broker(através do nome da conexão) e o remove

Get

Obtém um Cliente MQTT dado um nome

List

Lista os Clientes MQTT existentes(criados através da função Connect)

mqtt_connection = MqttClient.Connect(connection_name, client_parameters)

Descrição:

  • Cria um novo Cliente MQTT e abre a conexão com o BROKER conforme especificado por client_parameters. Registra o nome da conexão (connection_name) no gerenciador MqttClient, de forma que esta conexão possa ser recuperada por outro script dado seu nome de registro. É possível criar apenas um Cliente MQTT com o mesmo nome(connection_name).

Parâmetros de entrada:

  • connection_name: string com nome de registro da conexão referente ao Cliente MQTT;

  • client_parameters: tabela Lua com a configuração do Cliente MQTT e acesso ao Broker. Os parâmetros dependem do BROKER MQTT alvo e sua configuração. As chaves da tabela de configuração devem ser as seguintes:

Parâmetro

Descrição

Obrigatório

Default

broker_host

Endereço(IP ou URL) de acesso ao Broker MQTT

Sim

(Nenhum)

broker_port

Número da porta de acesso ao Broker MQTT

Sim

1883

client_id

ID do cliente MQTT a ser utilizado pela conexão

Não

(Nenhum)

user_name

Nome do usuário da conexão

Não

(Nenhum)

user_password

Senha do usuário da conexão

Não

(Nenhum)

keepalive

Tempo(em segundos) de keepalive para este cliente

Não

60

clean_session

Flag(true ou false) que define a utilização de uma seção limpa na conexão com o Broker

Não

true

is_tls_connection

Flag(true ou false) que define a utilização de uma conexão segura(TLS) com o broker MQTT

Não

false

certificate_path

Caminho completo até o arquivo de certificado a ser utilizado na conexão segura com o Broker

Não

(Nenhum)

is_mqtt5_connection

Flag(true ou false) que define a utilização de uma conexão MQTT5 com o Broker

Não

false

timeout_to_connect

Tempo(em segundos) de aguardo para conexão com o broker

Não

5

timeout_to_publish

Tempo(em segundos) de aguardo para publicações em tópicos. Após o timeout, será considerada uma falha

Não

5

auto_reconnect

Flag(true ou false) que define se o Cliente MQTT se reconectará de maneira automática ao Broker em caso de falha(queda) na conexão

Não

true

reconnect_min_delay

Tempo(em segundos) de aguardo mínimo antes de tentar uma nova conexão com o Broker

Não

10

reconnect_max_delay

Tempo(em segundos) de aguardo máximo antes de tentar uma nova conexão com o Broker

Não

60

will_topic

Tópico da mensagem de último testamento

Não

(Nenhum)

will_payload

Payload(conteúdo) da mensagem de último testamento

Não

(Nenhum)

will_qos

Qualidade de Serviço(0, 1 ou 2) da mensagem de último testamento

Não

0

will_retain

Flag de retenção(true ou false) da mensagem de último testamento

Não

false

on_message_script_name

Caminho completo até o script que será executado quando este Cliente MQTT receber o conteúdo de publicações

Não

(Nenhum)

on_connect_script_name

Caminho completo até o script que será executado no evento de CONEXÃO deste Cliente MQTT com o Broker

Não

(Nenhum)

on_disconnect_script_name

Caminho completo até o script que será executado no evento de DESCONEXÃO deste Cliente MQTT com o Broker

Não

(Nenhum)

Parâmetros de saída:

  • Instância de conexão referente ao Cliente MQTT ou nil caso não seja possível abrir conexão com o Broker MQTT.

  • A instância de conexão possui os atributos Name e Error.

Exemplo de utilização:

--------------------------------------------------------------------------------
-- Define tabela LUA com os parâmetros de configuração do cliente MQTT
--------------------------------------------------------------------------------
local client_parameters = {
  broker_host='broker.mqtt.hitecnologia.com.br',
  broker_port=8883,
  client_id='f88c0533',
  user_name='codigo_chave_acesso',
  user_password='',
  keepalive=30,
  clean_session=true,
  is_tls_connection=true,
  certificate_path='C:\\Users\\Public\\Documents\\HI_tecnologia\\HIscada_Pro\\1.7\\SCADA_1\\Kernel\\Projects\\exemplo_cliente_mqtt\\ca.pem',
  is_mqtt5_connection=false,
  timeout_to_connect=5,
  timeout_to_publish=5,
  reconnect_min_delay=5,
  reconnect_max_delay=120,
  will_topic=nil,
  will_payload=nil,
  will_qos=0,
  will_retain=false,
  will_properties=nil,
  on_message_script_name='Kernel.Scripts.ScriptGroup_Geral.Script_TrataMensagensMqtt',
  on_connect_script_name='Kernel.Scripts.ScriptGroup_Geral.Script_TrataEventoAposConexaoMqtt',
  on_disconnect_script_name='Kernel.Scripts.ScriptGroup_Geral.Script_TrataEventoAposDesconexaoMqtt'
}

--------------------------------------------------------------------------------
-- Declara variável de nome da conexão
--------------------------------------------------------------------------------
local connection_name = 'cliente_1'

--------------------------------------------------------------------------------
-- Realiza a conexão do Cliente MQTT com o Broker conforme os parâmetros
-- definidos anteriormente:
--  - connection_name: nome de identificação do Cliente MQTT
--  - client_parameters: Tabela LUA com a definição dos parâmetros do Cliente MQTT
--------------------------------------------------------------------------------
local mqtt_connection = MqttClient.Connect(connection_name, client_parameters)

--------------------------------------------------------------------------------
-- Verifica se houve algum erro de conexão do Cliente MQTT com o Broker.
-- Neste caso, o atributo Error da conexão será diferente de nil(nulo)
--------------------------------------------------------------------------------
if (mqtt_connection.Error ~= nil) then
  print("Erro ao abrir conexão [" .. connection_name .. "] com o BROKER: " .. mqtt_connection.Error)
  return
else
  print("Conexão com o BROKER MQTT realizada com sucesso!")
  print("Nome da Conexão: " ..  tostring(mqtt_connection))
  print("Nome da Conexão obtida: " ..  mqtt_connection.Name) -- forma alternativa
end

Após a conexão com sucesso ao BROKER MQTT, é possível executar um script associado a este evento utilizando o parâmetro on_connect_script_name na conexão do Cliente MQTT.

Neste script, as informações ficam disponíveis no objeto global

chamado MQTTConnection.

Neste objeto, estão disponíveis as seguintes informações:

Atributo

Descrição

Name

Nome da conexão associada ao evento de conexão com o Broker MQTT

ClientID

ID do cliente associado a conexão

Exemplo de utilização:

-----------------------------------------------------------------------------------
-- Exibe o nome da conexão MQTT associada ao evento de CONEXÃO com o Broker MQTT
-----------------------------------------------------------------------------------
print("ConnectionName: " .. MQTTConnection.Name)

-----------------------------------------------------------------------------------
-- Exibe a identificação do cliente MQTT(client_id)
-----------------------------------------------------------------------------------
print("ClientID: " .. MQTTConnection.ClientID)

ate

Em relação aos eventuais scripts que sejam configurados no Cliente MQTT para tratarem os eventos de conexão, desconexão e recebimento de mensagens, é importante que se atente ao código que será utilizado nestes scripts para que o seu processamento seja rápido e não impacte no tratamento de novos eventos. Portanto, deve-se evitar utilizar temporizações, laços de repetições e lógicas complexas.

mqtt_connection = MqttClient.Get(connection_name)

Descrição:

  • Recupera uma instância de conexão de um Cliente MQTT dado o seu nome, desde que a conexão tenha sido previamente criada. O método Get permite que scripts recuperem conexões que não foram eles próprios que abriram. Este recurso permite a criação de um pool de conexões permanentemente abertas com o Broker MQTT.

Parâmetros de entrada:

  • connection_name: string com nome da conexão.

Parâmetros de saída:

  • Instância de conexão ou nil caso não exista conexão com este nome.

Exemplo de utilização utilizando-se o nome da conexão:

--------------------------------------------------------------------------------
-- Declara variável de nome da conexão
--------------------------------------------------------------------------------
local connection_name = 'cliente_1'

--------------------------------------------------------------------------------
-- Após a conexão de um Cliente MQTT com o Broker, esta conexão pode ser obtida
-- em qualquer script(do KERNEL) através do nome utilizado na abertura da conexão
--------------------------------------------------------------------------------
local mqtt_connection = MqttClient.Get(connection_name)
if (mqtt_connection == nil) then
  print("Não foi possível obter a conexão: " .. connection_name)
  return
else
  print("Nome da Conexão obtida: " ..  tostring(mqtt_connection))
end

disconnect_result, disconnect_error = MqttClient.Disconnect(connection_name)

Descrição:

  • Encerra uma conexão referente ao Cliente MQTT que tenha sido previamente criada dado seu nome e remove o Cliente MQTT. Dessa forma, o nome utilizado para sua criação e conexão(através da função Connect) fica novamente disponível.

Parâmetros de entrada:

  • connection_name: string com nome da conexão.

Parâmetros de saída:

  • disconnect_result: Booleano indicando true se a conexão foi de fato encontrada e encerrada, ou false caso não tenha encontrado a conexão.

  • disconnect_error: Nulo(nil) indicando que não houve erro na desconexão ou o texto referente ao eventual erro que ocorreu neste processo.

Exemplo de utilização:

--------------------------------------------------------------------------------
-- Declara variável de nome da conexão
--------------------------------------------------------------------------------
local connection_name = 'cliente_1'

--------------------------------------------------------------------------------
-- Realiza a desconexão do Cliente MQTT do Broker
--------------------------------------------------------------------------------
local disconnect_result, disconnect_error = MqttClient.Disconnect(connection_name)

--------------------------------------------------------------------------------
-- Verifica os resultados de execução da função
--------------------------------------------------------------------------------
if (disconnect_result == false) then
  if (disconnect_error ~= nil) then
    print("Erro na desconexão do cliente MQTT [" .. connection_name .. "]: " .. disconnect_error)
  else
    print("Erro na desconexão do cliente MQTT [" .. connection_name .. "]")
  end
  return
else
  print("Desconexão do cliente MQTT [" .. connection_name .. "] realizada com sucesso")
end

Após a desconexão do Cliente MQTT com BROKER MQTT, (que pode ocorrer por diversos motivos, seja execução do comando acima ou por algum evento externo ao Cliente MQTT), é possível executar um script associado a este evento utilizando o parâmetro on_disconnect_script_name na conexão do Cliente MQTT.

Neste script, as informações ficam disponíveis no objeto global chamado MQTTConnection.

Neste objeto, estão disponíveis as seguintes informações:

Atributo

Descrição

Name

Nome da conexão associada ao evento de desconexão com o Broker MQTT

ClientID

ID do cliente associado a conexão

Exemplo de utilização:

-----------------------------------------------------------------------------------
-- Exibe o nome da conexão MQTT associada ao evento de DESCONEXÃO com o Broker MQTT
-----------------------------------------------------------------------------------
print("ConnectionName: " .. MQTTConnection.Name)

-----------------------------------------------------------------------------------
-- Exibe a identificação do cliente MQTT(client_id)
-----------------------------------------------------------------------------------
print("ClientID: " .. MQTTConnection.ClientID)

mqtt_clients_table = MqttClient.List()

Descrição:

  • Lista todas as instâncias de Clientes MQTT criadas em algum momento.

Parâmetros de saída:

  • Tabela LUA cujas chaves são os nomes de conexão, e os valores são instâncias de conexão, da mesma forma que as retornadas por MqttClient.Get().

Exemplo de utilização:

--------------------------------------------------------------------------------
-- Monta tabela LUA com os parâmetros do Cliente MQTT(simplificado)
--------------------------------------------------------------------------------
local client_parameters = {
  broker_host='IP_OU_URL_DO_BROKER',
  broker_port=1883
}

--------------------------------------------------------------------------------
-- Realiza 3 conexões com o Broker MQTT definido em client_parameters.
-- Neste exemplo, foram feitas algumas simplificações no código como não
-- testar os códigos de retorno das aberturas de conexões e também não
-- informado um client_id da conexão(alguns brokers aceitam esse tipo de
-- chamada e outros não).
--------------------------------------------------------------------------------
local mqtt_connection_1 = MqttClient.Connect('cliente_1', client_parameters)
local mqtt_connection_2 = MqttClient.Connect('cliente_2', client_parameters)
local mqtt_connection_3 = MqttClient.Connect('cliente_3', client_parameters)

--------------------------------------------------------------------------------
-- Obtém a lista das conexões que foram abertas, exibe essas informações no
-- console e fecha as conexões
--------------------------------------------------------------------------------
for conn_name, mqtt_conn in pairs(MqttClient.List()) do
  print("Nome da Conexão: " .. conn_name)
  print("Objeto da Conexão: " .. tostring(mqtt_conn))
  print("Nome da Conexão: " .. tostring(mqtt_conn.Name))
  print("Erro da Conexão: " .. tostring(mqtt_conn.Error))

  -- Desconecta o cliente através de seu nome
  MqttClient.Disconnect(name)
end

Funções de uma conexão(cliente) MQTT

As atuais funções de uma conexão associada a um Cliente MQTT, ou seja, do cliente MQTT criado e parametrizado através da função Connect do gerenciador MqttClient são as seguintes:

Função

Descrição

Publish

Realiza a publicação de algum conteúdo no tópico configurado

Subscribe

Realiza a assinatura do tópico configurado

Unsubscribe

Remove a assinatura do tópico configurado

IsConnected

Verifica se o Cliente MQTT está conectado ao Broker

Reconnect

Realiza uma reconexão do Cliente MQTT ao Broker(caso esteja desconectado)

pub_result, pub_error = mqtt_connection:Publish(publish_parameters)

Descrição:

  • Realiza a publicação no tópico conforme parâmetros definidos na chamada da função.

Parâmetros de entrada:

  • publish_parameters: tabela Lua com a configuração da publicação. As chaves da tabela de configuração devem ser as seguintes:

Parâmetro

Descrição

Obrigatório

Default

topic

Tópico a ser publicado no Broker MQTT

Sim

(Nenhum)

payload

Conteúdo da mensagem que será publicada no tópico

Sim

(Nenhum)

qos

Qualidade de Serviço(0, 1 ou 2) da publicação

Sim

(Nenhum)

retain

Flag que indica se a publicação será retentiva ou não

Sim

(Nenhum)

Parâmetros de saída:

  • pub_result: Booleano indicando true se a publicação foi realizada com sucesso ou indicando false se houve alguma falha.

  • pub_error: Nulo(nil) indicando que não houve erro na publicação ou o texto referente ao eventual erro que ocorreu neste processo.

Exemplo de utilização:

--------------------------------------------------------------------------------
-- Declara variáveis de nome da conexão e o tópico MQTT
--------------------------------------------------------------------------------
local connection_name = 'cliente_1'
local topic           = '9a3547bc/temperatura-forno'

--------------------------------------------------------------------------------
-- Obtém a conexão do Cliente MQTT(previamente aberta) através de seu nome
--------------------------------------------------------------------------------
local mqtt_connection = MqttClient.Get(connection_name)
if (mqtt_connection == nil) then
  print("Não foi possível obter a conexão: " .. connection_name)
  return
else
  print("Nome da Conexão obtida: " ..  tostring(mqtt_connection))
end

--------------------------------------------------------------------------------
-- Define uma tabela LUA com os parâmetros de publicação em um tópico:
-- - topic: definição do tópico a ser publicado no Broker
-- - payload: definição do conteúdo da mensagem que será publicada no tópico
-- - qos: definição da Qualidade de Serviço(0, 1 ou 2) da publicação
-- - retain: definição do flag de rentenção da publicação
--------------------------------------------------------------------------------
local publish_parameters = {
  topic=topic,
  payload='88.75',
  qos=0,
  retain=false
}

--------------------------------------------------------------------------------
-- Realiza a publicação nop tópico conforme parâmetros definidos anteriormente.
-- Nesta função, são retornados dois resultados:
-- - pub_result: retorna um flag indicando se a publicação foi realizada com sucesso(true) ou não(false)
-- - pub_error: em caso alguma falha na publicação, o erro será indicado  nesta variável
--------------------------------------------------------------------------------
local pub_result, pub_error = mqtt_connection:Publish(publish_parameters)

--------------------------------------------------------------------------------
-- Verifica os resultados de execução da função
--------------------------------------------------------------------------------
if (pub_result == false) then
  if (pub_error ~= nil) then
    print("Erro na publicação no topico[" .. topic .. "]:" .. pub_error)
  else
    print("Erro na publicação no tópico [" .. topic .. "]")
  end
  MqttClient.Disconnect(connection_name)
  return
else
  print("Publicação no tópico [" .. topic .. "] realizada com sucesso")
end

sub_result, sub_error = mqtt_connection:Subscribe(subscribe_parameters)

Descrição:

  • Realiza a assinatura do tópico conforme parâmetros definidos na chamada da função.

Parâmetros de entrada:

  • subscribe_parameters: tabela Lua com a configuração da assinatura. As chaves da tabela de configuração devem ser as seguintes:

Parâmetro

Descrição

Obrigatório

Default

topic

Tópico a ser assinado(subscrito) no Broker MQTT

Sim

(Nenhum)

qos

Qualidade de Serviço(0, 1 ou 2) da assinatura

Sim

(Nenhum)

Parâmetros de saída:

  • sub_result: Booleano indicando true se a assinatura foi realizada com sucesso ou indicando false se houve alguma falha.

  • sub_error: Nulo(nil) indicando que não houve erro na assinatura ou o texto referente ao eventual erro que ocorreu neste processo.

Exemplo de utilização:

--------------------------------------------------------------------------------
-- Declara variáveis de nome da conexão e o tópico MQTT
--------------------------------------------------------------------------------
local connection_name = 'cliente_1'
local topic           = '9a3547bc/temperatura-forno'

--------------------------------------------------------------------------------
-- Obtém a conexão do Cliente MQTT(previamente aberta) através de seu nome
--------------------------------------------------------------------------------
local mqtt_connection = MqttClient.Get(connection_name)
if (mqtt_connection == nil) then
  print("Não foi possível obter a conexão: " .. connection_name)
  return
else
  print("Nome da Conexão obtida: " ..  tostring(mqtt_connection))
end

--------------------------------------------------------------------------------
-- Define uma tabela LUA com os parâmetros de assinatura de um tópico:
--  - topic: definição do tópico a ser assinado(subscrito) no Broker
--  - qos: definição da Qualidade de Serviço(0, 1 ou 2) da assinatura
--------------------------------------------------------------------------------
local subscribe_parameters = {
  topic=topic,
  qos=0
}

--------------------------------------------------------------------------------
-- Realiza a assinatura do tópico conforme parâmetros definidos anteriormente.
-- Nesta função, são retornados dois resultados:
--  - sub_result: retorna um flag indicando se a assinatura foi realizada com sucesso(true) ou não(false)
--  - sub_error: em caso alguma falha na assinatura, o erro será indicado nesta variável
--------------------------------------------------------------------------------
local sub_result, sub_error = mqtt_connection:Subscribe(subscribe_parameters)

--------------------------------------------------------------------------------
-- Verifica os resultados de execução da função
--------------------------------------------------------------------------------
if (sub_result == false) then
  if (sub_error ~= nil) then
    print("Erro na assinatura do tópico [" .. topic .. "]: " .. sub_error)
  else
    print("Erro na assinatura do tópico [" .. topic .. "]")
  end
  MqttClient.Disconnect(connection_name)
  return
else
  print("Assinatura do tópico [" .. topic .. "] realizada com sucesso")
end

Após a assinatura de qualquer tópico, os eventuais conteúdos publicados no mesmo poderão ser obtidos através do script fornecido no parâmetro on_message_script_name na conexão do Cliente MQTT.

Neste script, as informações ficam disponíveis no objeto global chamado MQTTMessage.

Neste objeto, estão disponíveis as seguintes informações:

Atributo

Descrição

ConnectionName

Nome da conexão que realizou a assinatura do tópico

ClientID

ID do cliente associado a conexão

Topic

Tópico associado a mensagem recebida

Payload

Conteúdo da mensagem

Exemplo de utilização:

----------------------------------------------------------------------------
-- Exibe o nome da conexão MQTT que assinou o tópico a mensagem
----------------------------------------------------------------------------
print("ConnectionName: " .. MQTTMessage.ConnectionName)

----------------------------------------------------------------------------
-- Exibe a identificação do cliente MQTT(client_id)
----------------------------------------------------------------------------
print("ClientID: " .. MQTTMessage.ClientID)

----------------------------------------------------------------------------
-- Exibe tópico associado a mensagem recebida do tópico assinado
----------------------------------------------------------------------------
print("Topic: " .. MQTTMessage.Topic)

----------------------------------------------------------------------------
-- Exibe o conteúdo da mensagem recebida do tópico assinado
----------------------------------------------------------------------------
print("Payload: " .. MQTTMessage.Payload)

unsub_result, unsub_error = mqtt_connection:Unsubscribe(unsubscribe_parameters)

Descrição:

  • Remove a assinatura do tópico conforme parâmetros definidos na chamada da função.

Parâmetros de entrada:

  • unsubscribe_parameters: tabela Lua com a configuração da remoção de assinatura. As chaves da tabela de configuração devem ser as seguintes:

Parâmetro

Descrição

Obrigatório

Default

topic

Tópico a ser removida a assinatura no Broker MQTT

Sim

(Nenhum)

Parâmetros de saída:

  • unsub_result: Booleano indicando true se a assinatura foi realizada com sucesso ou indicando false se houve alguma falha.

  • unsub_error: Nulo(nil) indicando que não houve erro na assinatura ou o texto referente ao eventual erro que ocorreu neste processo.

Exemplo de utilização:

--------------------------------------------------------------------------------
-- Declara variáveis de nome da conexão e o tópico MQTT
--------------------------------------------------------------------------------
local connection_name = 'cliente_1'
local topic           = '9a3547bc/temperatura-forno'

--------------------------------------------------------------------------------
-- Obtém a conexão do Cliente MQTT(previamente aberta) através de seu nome
--------------------------------------------------------------------------------
local mqtt_connection = MqttClient.Get(connection_name)
if (mqtt_connection == nil) then
  print("Não foi possível obter a conexão: " .. connection_name)
  return
else
  print("Nome da Conexão obtida: " ..  tostring(mqtt_connection))
end

--------------------------------------------------------------------------------
-- Define uma tabela LUA com os parâmetros de remoção de assinatura de um tópico:
-- - topic: definição do tópico a ser removida a assinatura no Broker
--------------------------------------------------------------------------------
local unsubscribe_parameters = { topic=topic }

--------------------------------------------------------------------------------
-- Remove a assiantura do tópico conforme parâmetros definidos anteriormente.
-- Nesta função, são retornados dois resultados:
-- - unsub_result: retorna um flag indicando se a remoção de assinatura
--                 foi realizada com sucesso(true) ou não(false)
-- - unsub_error: em caso alguma falha na remoção da assinatura, o erro
--                será indicado nesta variável
--------------------------------------------------------------------------------
local unsub_result, unsub_error = mqtt_connection:Unsubscribe(unsubscribe_parameters)

--------------------------------------------------------------------------------
-- Verifica os resultados de execução da função
--------------------------------------------------------------------------------
if (unsub_result == false) then
  if (unsub_error ~= nil) then
    print("Erro na remoção de assinatura do topico[" .. topic .. "]:" .. unsub_error)
  else
    print("Erro na remoção de assinatura do topico[" .. topic .. "]")
  end
  return
else
  print("Remoção de assinatura do topico[" .. topic .. "] realizada com sucesso")
end

is_con_result, is_con_error = mqtt_connection:IsConnected()

Descrição:

  • Informa se o cliente está conectado(online) com o Broker MQTT.

Parâmetros de saída:

  • is_con_result: Booleano indicando true se o cliente estiver conectado ao Broker ou indicando false se estiver desconectado.

  • is_con_error: Nulo(nil) indicando que não houve erro na verificação da conexão com o Broker ou o texto referente ao eventual erro que ocorreu neste processo.

Exemplo de utilização:

--------------------------------------------------------------------------------
-- Declara variáveis de nome da conexão
--------------------------------------------------------------------------------
local connection_name = 'cliente_1'

--------------------------------------------------------------------------------
-- Obtém a conexão do cliente MQTT(previamente aberta) através de seu nome
--------------------------------------------------------------------------------
local mqtt_connection = MqttClient.Get(connection_name)
if (mqtt_connection == nil) then
  print("Não foi possível obter a conexão: " .. connection_name)
  return
else
  print("Nome da Conexão obtida: " ..  tostring(mqtt_connection))
end

--------------------------------------------------------------------------------
-- Executa a função com verifica se o cliente está conectado ao Broker MQTT.
-- Nesta função, são retornados dois resultados:
-- - is_con_result: retorna um flag indicando se o cliente esta conectado ao
--                  Broker MQTT(true) ou não(false)
-- - is_con_error: em caso alguma falha na verificação de conexão, o erro
--                 será indicado nesta variável
--------------------------------------------------------------------------------
local is_con_result, is_con_error = mqtt_connection:IsConnected()

--------------------------------------------------------------------------------
-- Verifica os resultados de execução da função
--------------------------------------------------------------------------------
if (is_con_result == false) then
  if (is_con_error ~= nil) then
    print("Erro na verificação de conexão [" .. connection_name .. "] com Broker MQTT: " .. is_con_error)
  else
    print("Conexão [" .. connection_name .. "] OFFLINE com o Broker MQTT")
  end
  return
else
  print("Conexão [" .. connection_name .. "] ONLINE com o Broker MQTT")
end

recon_result, recon_error = mqtt_connection:Reconnect()

Descrição:

  • Realiza uma reconexão do cliente com o Broker MQTT caso a mesmo esteja offline(desconectado). Essa função é útil principalmente quando o parâmetro auto_reconnect é definido como false na criação/conexão do cliente com o broker(função connect).

Parâmetros de saída:

  • recon_result: Booleano indicando true se a reconexão foi realizada com sucesso ou se o cliente já estiver conectado ao Broker ou indicando false se houve alguma falha.

  • recon_error: Nulo(nil) indicando que não houve erro na reconexão do cliente com o Broker ou o texto referente ao eventual erro que ocorreu neste processo.

Exemplo de utilização:

--------------------------------------------------------------------------------
-- Declara variáveis de nome da conexão
--------------------------------------------------------------------------------
local connection_name = 'cliente_1'

--------------------------------------------------------------------------------
-- Obtém a conexão do cliente MQTT(previamente aberta) através de seu nome
--------------------------------------------------------------------------------
local mqtt_connection = MqttClient.Get(connection_name)
if (mqtt_connection == nil) then
  print("Não foi possível obter a conexão: " .. connection_name)
  return
else
  print("Nome da Conexão obtida: " ..  tostring(mqtt_connection))
end

--------------------------------------------------------------------------------
-- Executa a função de reconexão do cliente com o Broker MQTT
-- Nesta função, são retornados dois resultados:
-- - recon_result: retorna um flag indicando se a reconexão do cliente
--                 foi realizada com sucesso(true) ou não(false)
-- - recon_error: em caso alguma falha na reconexão do cliente, o erro
--                será indicado nesta variável
--------------------------------------------------------------------------------
local recon_result, recon_error = mqtt_connection:Reconnect()

--------------------------------------------------------------------------------
-- Verifica os resultados de execução da função
--------------------------------------------------------------------------------
if (recon_result == false) then
  if (recon_error ~= nil) then
    print("Erro na reconexão do cliente [" .. connection_name .. "] com Broker MQTT: " .. recon_error)
  else
    print("Erro na reconexão do cliente [" .. connection_name .. "] com Broker MQTT")
  end
  return
else
  print("Reconexão do cliente [" .. connection_name .. "] com o Broker MQTT realizada com sucesso")
end

Exemplo de Utilização

O cenário de exemplo que iremos utilizar para demonstrar o funcionamento de um Cliente MQTT do HIscada Pro considera a interface e recursos MQTT do Portal de Telemetria da HI Tecnologia.

O Portal de Telemetria possui um Broker MQTT para que sejam enviadas(publicadas) e recebidas(assinadas) informações referentes a equipamentos que são monitorados pelo mesmo.

Para mais informações sobre a interface MQTT do Portal de Telemetria, acesse: Utilizando o protocolo MQTT no Portal

Existem algumas maneiras de desenvolvermos este exemplo no HIscada Pro, porém, para fins didáticos, serão utilizados apenas dois scripts:

  • O primeiro script será responsável por criar a conexão do Cliente MQTT com o Broker do Portal de Telemetria, além de assinar um determinado tópico e realizar a publicação de um valor no mesmo.

  • Já o segundo script será responsável por receber as mensagens MQTT do tópico que foi assinado no primeiro script, além de remover essa assinatura e fechar a conexão do Cliente MQTT com o Broker do Portal.

Portanto, vamos ao código do primeiro script, que será responsável por abrir a conexão do Cliente MQTT com o Broker do Portal de Telemetria, assinar(subscrever) a recepção de mensagens do tópico 9a3547bc/temperatura-forno e realizar uma publicação neste mesmo tópico:

----------------------------------------------------------------------------
-- Declara variáveis de nome da conexão e o tópico MQTT
----------------------------------------------------------------------------
local connection_name = 'cliente_1'
local topic           = '9a3547bc/temperatura-forno'

----------------------------------------------------------------------------------------------------------------------------------------
-- Define tabela LUA com os parâmetros de configuração do cliente MQTT para acesso ao Broker do Portal de Telemetria via conexão segura.
-- O arquivo(ca.pem) de certificado deve ser obtido no cadastro do Conector no Portal e armazenado no diretório do projeto do HIscada Pro.
-- Também no cadastro do Conector, deve ser obtido o Identificador MQTT do Conector(9a3547bc) e utilizado no parâmetro client_id.
-- Já Chave de Acesso(codigo_chave_acesso) deve ser obtida nas informações do Contrato no Portal e utilizada no parâmetro user_name.
-- Por fim, foi informado o caminho completo do segundo script(no parâmetro on_message_script_name) que tratará as mensagens MQTT.
----------------------------------------------------------------------------------------------------------------------------------------
local client_parameters = {
  broker_host='broker.mqtt.hitecnologia.com.br',
  broker_port=8883,
  client_id='9a3547bc',
  user_name='codigo_chave_acesso',
  user_password='',
  is_tls_connection=true,
  certificate_path='C:\\Users\\Public\\Documents\\HI_tecnologia\\HIscada_Pro\\1.7\\SCADA_1\\Kernel\\Projects\\exemplo_cliente_mqtt\\ca.pem',
  on_message_script_name='Kernel.Scripts.ScriptGroup_Geral.Script_TrataMensagensMqtt'
}

-------------------------------------------------------------------------------------------------
-- Realiza a conexão do Cliente MQTT com o Broker conforme os parâmetros definidos anteriormente:
--  - connection_name: nome de identificação do Cliente MQTT
--  - client_parameters: Tabela LUA com a definição dos parâmetros do Cliente MQTT
-------------------------------------------------------------------------------------------------
local mqtt_connection = MqttClient.Connect(connection_name, client_parameters)

--------------------------------------------------------------------------------
-- Verifica se houve algum erro de conexão do Cliente MQTT com o Broker.
-- Neste caso, o atributo Error da conexão será diferente de nil
--------------------------------------------------------------------------------
if (mqtt_connection.Error ~= nil) then
  print("Erro ao abrir conexão [" .. connection_name .. "] com o BROKER: " .. mqtt_connection.Error)
  return
else
  print("Conexão com o BROKER MQTT realizada com sucesso!")
  print("Nome da Conexão: " ..  tostring(mqtt_connection))
end

print("\n")

--------------------------------------------------------------------------------
-- Define uma tabela LUA com os parâmetros de assinatura de um tópico:
--  - topic: definição do tópico a ser assinado(subscrito) no Broker
--  - qos: definição da Qualidade de Serviço(0, 1 ou 2) da assinatura
--------------------------------------------------------------------------------
local subscribe_parameters = {
  topic=topic,
  qos=0
}

----------------------------------------------------------------------------------------------------------
-- Realiza a assinatura do tópico conforme parâmetros definidos anteriormente.
-- Nesta função, são retornados dois resultados:
--  - sub_result: retorna um flag indicando se a assinatura foi realizada com sucesso(true) ou não(false)
--  - sub_error: em caso alguma falha na assinatura, o erro será indicado nesta variável
----------------------------------------------------------------------------------------------------------
local sub_result, sub_error = mqtt_connection:Subscribe(subscribe_parameters)

--------------------------------------------------------------------------------
-- Verifica os resultados de execução da função
--------------------------------------------------------------------------------
if (sub_result == false) then
  if (sub_error ~= nil) then
    print("Erro na assinatura do tópico [" .. topic .. "]: " .. sub_error)
  else
    print("Erro na assinatura do tópico [" .. topic .. "]")
  end
  MqttClient.Disconnect(connection_name)
  return
else
  print("Assinatura do tópico [" .. topic .. "] realizada com sucesso")
end

print("\n")

--------------------------------------------------------------------------------
-- Define uma tabela LUA com os parâmetros de publicação em um tópico:
-- - topic: definição do tópico a ser publicado no Broker
-- - payload: definição do conteúdo da mensagem que será publicada no tópico
-- - qos: definição da Qualidade de Serviço(0, 1 ou 2) da publicação
-- - retain: definição do flag de retenção da publicação
--------------------------------------------------------------------------------
local publish_parameters = {
  topic=topic,
  payload='88.75',
  qos=0,
  retain=false
}

----------------------------------------------------------------------------------------------------------
-- Realiza a publicação no tópico conforme parâmetros definidos anteriormente.
-- Nesta função, são retornados dois resultados:
-- - pub_result: retorna um flag indicando se a publicação foi realizada com sucesso(true) ou não(false)
-- - pub_error: em caso alguma falha na publicação, o erro será indicado  nesta variável
----------------------------------------------------------------------------------------------------------
local pub_result, pub_error = mqtt_connection:Publish(publish_parameters)

--------------------------------------------------------------------------------
-- Verifica os resultados de execução da função
--------------------------------------------------------------------------------
if (pub_result == false) then
  if (pub_error ~= nil) then
    print("Erro na publicação no topico[" .. topic .. "]:" .. pub_error)
  else
    print("Erro na publicação no tópico [" .. topic .. "]")
  end
  MqttClient.Disconnect(connection_name)
  return
else
  print("Publicação no tópico [" .. topic .. "] realizada com sucesso")
end

A seguir, segue o código do segundo script, cujo o caminho completo até o mesmo deve ser informado no parâmetro on_message_script_name da função Connect do Cliente MQTT.

Este script será responsável por tratar as mensagens MQTT que serão recebidas pelo Cliente com as publicações realizadas no tópico 9a3547bc/temperatura-forno, além de remover a assinatura deste tópico e fechar a conexão com o Broker do Portal de Telemetria:

ate

O exemplo abaixo utiliza um módulo externo LUA chamado json.lua para realizar a conversão do payload recebido da publicação(que é em JSON) para uma tabela LUA. Copie o conteúdo deste módulo clicando aqui e crie um arquivo chamado json.lua no diretório LUA do projeto com este conteúdo. O roteiro de criação de módulos externos documenta e exemplifica como criar módulos de funções.

----------------------------------------------------------------------------
-- Declara variáveis de nome da conexão e o tópico MQTT
----------------------------------------------------------------------------
local connection_name = 'cliente_1'
local topic           = '9a3547bc/temperatura-forno'

print("\n")

----------------------------------------------------------------------------
-- Exibe o nome da conexão MQTT que assinou o tópico a mensagem
----------------------------------------------------------------------------
print("Informações da mensagem MQTT recebida da assinatura:")
print("--> ConnectionName: " .. MQTTMessage.ConnectionName)

----------------------------------------------------------------------------
-- Exibe a identificação do cliente MQTT(client_id)
----------------------------------------------------------------------------
print("--> ClientID: " .. MQTTMessage.ClientID)

----------------------------------------------------------------------------
-- Exibe tópico associado a mensagem recebida do tópico assinado
----------------------------------------------------------------------------
print("--> Topic: " .. MQTTMessage.Topic)

----------------------------------------------------------------------------
-- Exibe o conteúdo da mensagem recebida do tópico assinado
----------------------------------------------------------------------------
print("--> Payload: " .. MQTTMessage.Payload .. "\n")

----------------------------------------------------------------------------
-- Importa módulo de manipulação de objetos JSON via LUA
----------------------------------------------------------------------------
local JSON = require("JSON")

----------------------------------------------------------------------------
-- Caso o tópico seja o da publicação de valor
----------------------------------------------------------------------------
if (MQTTMessage.Topic == topic) then

  --------------------------------------------------------------------------
  -- Transforma o payload recebido(string JSON) em uma tabela LUA
  -- Exemplo do JSON: {"timestamp": 1672949269124, "value": 88.75}
  -- Exemplo Tabela LUA: {["timestamp"] = 1672949269124, ["value"] = 88.75}
  --------------------------------------------------------------------------
  local lua_table_json  = JSON:decode(MQTTMessage.Payload)

  -- Obtém o valor do Dado informado no payload
  local topic_value = lua_table_json['value']

  -- Obtém o timestamp associado ao valor do Dado informado no payload
  -- Exemplo: 1672949269124
  local topic_timestamp = lua_table_json['timestamp']

  -- Transforma o timestamp obtido em um um Datetime LUA(em UTC)
  -- Exemplo: 05/01/2023 20:07:49
  local topic_datetime = DateTime.FromEpochTime(topic_timestamp/1000)

  -- Converte o timezone da data/hora de UTC para America/Sao_Paulo(-3 horas)
  -- Exemplo: 05/01/2023 17:07:49
  local topic_datetime_with_tz = DateTime(topic_datetime:GetValue() - 3/24)

  -- Exibe o valor e a data/hora do tópico associado ao payload recebido
  print("--> Valor: " .. topic_value .. "\n")
  print("--> Data/hora: " .. tostring(topic_datetime_with_tz) .. "\n")

end

--------------------------------------------------------------------------------
-- Obtém conexão com o Broker MQTT através do nome utilizado em sua abertura
--------------------------------------------------------------------------------
local mqtt_connection = MqttClient.Get(connection_name)
if (mqtt_connection == nil) then
  print("Não foi possível obter a conexão!")
  return
else
  print("Nome da Conexão obtida: " ..  tostring(mqtt_connection))
end

print("\n")

--------------------------------------------------------------------------------
-- Define uma tabela LUA com os parâmetros de remoção de assinatura de um tópico:
-- - topic: definição do tópico a ser removida a assinatura no BROKER
--------------------------------------------------------------------------------
local unsubscribe_parameters = {
  topic=topic
}

--------------------------------------------------------------------------------
-- Remove a assiantura do tópico conforme parâmetros definidos anteriormente.
-- Nesta função, são retornados dois resultados:
-- - unsub_result: retorna um flag indicando se a remoção de assinatura
--                 foi realizada com sucesso(true) ou não(false)
-- - unsub_error: em caso alguma falha na remoção da assinatura, o erro
--                será indicado nesta variável
--------------------------------------------------------------------------------
local unsub_result, unsub_error = mqtt_connection:Unsubscribe(unsubscribe_parameters)

--------------------------------------------------------------------------------
-- Caso a variável unsubscribe_result seja false, indica que houve um erro na
-- remoção de assinatura do tópico
--------------------------------------------------------------------------------
if (unsub_result == false) then
  if (unsub_error ~= nil) then
    print("Erro na remoção de assinatura do topico[" .. topic .. "]:" .. unsub_error)
  else
    print("Erro na remoção de assinatura do topico[" .. topic .. "]")
  end
  return
else
  print("Remoção de assinatura do topico[" .. topic .. "] realizada com sucesso")
end

print("\n")

--------------------------------------------------------------------------------
-- Obtém a lista das conexões que foram abertas, exibe essas informações no
-- console e fecha as conexões
--------------------------------------------------------------------------------
print("Lista de conexões:")
for conn_name, mqtt_conn in pairs(MqttClient.List()) do
  print("--> Nome da conexão: " .. conn_name)

  ------------------------------------------------------------------------------
  -- Realiza a desconexão do CLIENTE MQTT do BROKER
  ------------------------------------------------------------------------------
  local disconnect_result, disconnect_error = MqttClient.Disconnect(conn_name)

  ------------------------------------------------------------------------------
  -- Caso a variável disconnect_result seja false, indica que houve um erro na
  -- desconexão
  ------------------------------------------------------------------------------
  if (disconnect_result == false) then
    if (disconnect_error ~= nil) then
      print("--> Erro na desconexão do cliente MQTT [" .. conn_name .. "]: " .. disconnect_error)
    else
      print("--> Erro na desconexão do cliente MQTT [" .. conn_name .. "]")
    end
    return
  else
    print("--> Desconexão do cliente MQTT[" .. conn_name .. "] realizada com sucesso")
  end
end

Resultado da execução do exemplo acima:

Conexão com o BROKER MQTT realizada com sucesso!
Nome da Conexão: cliente_1

Assinatura do tópico [9a3547bc/temperatura-forno] realizada com sucesso

Publicação no tópico [9a3547bc/temperatura-forno] realizada com sucesso

Informações da mensagem MQTT recebida da assinatura:
--> ConnectionName: cliente_1
--> ClientID: 9a3547bc
--> Topic: 9a3547bc/temperatura-forno
--> Payload: {"value": 88.75, "timestamp": 1672949269124}
--> Valor: 88.75
--> Data/Hora: 05/01/2023 17:07:49

Nome da Conexão obtida: cliente_1

Remoção de assinatura do topico[9a3547bc/temperatura-forno] realizada com sucesso

Lista de conexões:
--> Nome da conexão: cliente_1
--> Desconexão do cliente MQTT[cliente_1] realizada com sucesso