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 (-1 = wildcard)
value = integer, -- Valor atual da leitura (int64_t)
previousValue = integer, -- Valor anterior da leitura
timestamp = integer -- Timestamp em milissegundos
}

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 (-1 = wildcard)
value = table, -- Array de bytes atual (1-indexed)
length = integer, -- Número de bytes no array value
previousValue = table, -- Array de bytes anterior (1-indexed)
previousLength = integer, -- Número de bytes no array previousValue
timestamp = integer -- Timestamp em milissegundos
}

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 (-1 = wildcard)
value = string, -- Texto atual
length = integer, -- Comprimento do texto atual
previousValue = string, -- Texto anterior
previousLength = integer, -- Comprimento do texto anterior
timestamp = integer -- Timestamp em milissegundos
}

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 (-1 = wildcard)
value = integer, -- Novo estado (int64_t)
previousValue = integer, -- Estado anterior
timestamp = integer -- Timestamp em milissegundos
}

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)

EventBus.subscribeWifi(callback)

Recebe eventos de conectividade WiFi.

Estrutura do evento:

{
connected = boolean, -- true se WiFi está conectado
timestamp = integer -- Timestamp em milissegundos
}

Exemplo de uso:

-- Monitora conectividade WiFi
EventBus.subscribeWifi(function(event)
if event.connected then
Log.success("WiFi conectado")
else
Log.warn("WiFi desconectado")
end
end)

Monitorando Múltiplas Fontes

Para monitorar todas as fontes de um tipo de evento, use sourceId = -1:

-- 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), -1 = wildcard
valuevariesValor atual (tipo depende do callback)
previousValuevariesValor anterior
timestampintegerTimestamp em milissegundos

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.