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:
| Campo | Tipo | Descrição |
|---|---|---|
sourceId | integer | ID da origem do evento (sensor ou device) |
value | varies | Valor atual (tipo depende do callback) |
previousValue | varies | Valor anterior |
timestamp | integer | Timestamp 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)
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)
Callbacks são executados de forma assíncrona. Evite operações bloqueantes ou muito demoradas dentro deles.