Skip to main content

Reagindo a Eventos

O Hermes utiliza um sistema de eventos assíncronos para reagir a mudanças de estado dos sensores e dispositivos. Todos os eventos são acessados através do objeto global EventBus.

Tipos de Callbacks

O EventBus oferece quatro tipos de callbacks especializados, cada um otimizado para um tipo específico de dado:

EventBus.subscribeScalar(sourceId, callback)

Recebe eventos com valores numéricos inteiros (sensores de temperatura, umidade, contadores, etc).

Estrutura do evento:

{
sourceId = integer, -- ID do sensor/dispositivo que gerou o evento
value = integer, -- Valor atual da leitura
previousValue = integer, -- Valor anterior da leitura
timestamp = integer -- Timestamp em microssegundos desde o boot
}

Exemplo de uso:

-- Monitora leituras do sensor de temperatura (ID 1)
EventBus.subscribeScalar(1, function(event)
local temp = event.value / 10 -- Temperatura em °C × 10
Log.info(string.format("Temperatura: %.1f°C", temp))
end)

EventBus.subscribeBytes(sourceId, callback)

Recebe eventos com arrays de bytes (dados binários, buffers, pacotes de rede).

Estrutura do evento:

{
sourceId = integer, -- ID da origem do evento
value = table, -- Array de bytes atual (indexado de 1)
length = integer, -- Tamanho do array atual
previousValue = table, -- Array de bytes anterior
previousLength = integer, -- Tamanho do array anterior
timestamp = integer -- Timestamp em microssegundos
}

Exemplo de uso:

-- Processa dados binários de um sensor serial
EventBus.subscribeBytes(5, function(event)
Log.info(string.format("Recebidos %d bytes", event.length))

-- Acessa bytes individuais (Lua indexa de 1)
for i = 1, event.length do
print(string.format("Byte %d: 0x%02X", i, event.value[i]))
end
end)

EventBus.subscribeText(sourceId, callback)

Recebe eventos com strings de texto (GPS/modbus).

Estrutura do evento:

{
sourceId = integer, -- ID da origem do evento
value = string, -- Texto atual
length = integer, -- Tamanho da string atual
previousValue = string, -- Texto anterior
previousLength = integer, -- Tamanho da string anterior
timestamp = integer -- Timestamp em microssegundos
}

Exemplo de uso:

-- Monitora mensagens de um dispositivo UART
EventBus.subscribeText(10, function(event)
Log.info(string.format("Mensagem recebida: '%s'", event.value))

if event.value:match("ERROR") then
Log.error("Erro detectado no dispositivo!")
end
end)

EventBus.subscribeState(sourceId, callback)

Recebe eventos de mudança de estado (dispositivos ON/OFF, PWM, modos de operação).

Estrutura do evento:

{
sourceId = integer, -- ID do dispositivo que mudou de estado
value = integer, -- Novo estado (0/1 para ON_OFF, 0-100 para PWM)
previousValue = integer, -- Estado anterior
timestamp = integer -- Timestamp em microssegundos
}

Exemplo de uso:

-- Monitora mudanças de estado de um relé
EventBus.subscribeState(3, function(event)
if event.value == 1 then
Log.success(string.format("Dispositivo %d LIGADO", event.sourceId))
else
Log.info(string.format("Dispositivo %d DESLIGADO", event.sourceId))
end
end)

Monitorando Múltiplas Fontes

Para monitorar todas as fontes de um tipo de evento, use sourceId = -1 ou simplesmente omita o parâmetro:

-- Monitora TODOS os eventos de estado
EventBus.subscribeState(-1, function(event)
print(string.format("Dispositivo %d mudou para estado %d",
event.sourceId, event.value))
end)

Campos Comuns

Todos os eventos compartilham estes campos:

CampoTipoDescrição
sourceIdintegerID da origem do evento (sensor ou device)
valuevariesValor atual (tipo depende do callback)
previousValuevariesValor anterior
timestampintegerTimestamp em microssegundos desde o boot

Exemplos Práticos

Controlar ventilador baseado em temperatura

-- Sensor de temperatura (ID 2) controla ventilador (Device ID 1)
EventBus.subscribeScalar(2, function(event)
local fan = Device.get(1)
local temp = event.value / 10 -- Temperatura em °C × 10

if temp > 30 then
fan:setState(100) -- Velocidade máxima
Log.warn("Temperatura alta: ventilador em 100%")
elseif temp > 25 then
fan:setState(50) -- Velocidade média
else
fan:setState(0) -- Desligado
end
end)

Sincronizar sensor com estado de bomba

-- Quando bomba (Device 0) liga/desliga, controla sensor
EventBus.subscribeState(0, function(event)
local sensor = Sensor.get(0)

if event.value == 1 then
sensor:resume()
sensor:resetTimer()
Log.info("Bomba ligada: sensor ativado")
else
sensor:pause()
Log.info("Bomba desligada: sensor pausado")
end
end)

Dica: Escolha do Callback

Use o callback mais específico para seu tipo de dado:

  • subscribeState: Mudanças de estado de dispositivos
  • subscribeScalar: Valores numéricos (analogicos/digitais)
  • subscribeBytes: Dados binários/protocolos personalizados (SPI/i2c/modbus)
  • subscribeText: Mensagens e strings (GPS/modbus)
Atenção

Callbacks são executados de forma assíncrona. Evite operações bloqueantes ou muito demoradas dentro deles.