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:
| Campo | Tipo | Descrição |
|---|---|---|
sourceId | integer | ID da origem do evento (sensor ou device), -1 = wildcard |
value | varies | Valor atual (tipo depende do callback) |
previousValue | varies | Valor anterior |
timestamp | integer | Timestamp 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)
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.