# Motor de Regras — "SE isso, ENTÃO aquilo"

Guia para configurar regras de automação no Nexus. É a **"formatação condicional"**
do condomínio: você diz o que observar e o que fazer quando acontecer.

Uma regra tem três partes:

| Parte | O que é |
|---|---|
| **SE** (gatilho) | O que faz a regra "acordar" — um acesso, um horário, o pôr do sol, um sensor… |
| **E / OU** (condições) | Conferências extras no momento do disparo (opcional) |
| **ENTÃO** (ações) | O que fazer — **várias**, em ordem, cada uma podendo ter atraso |

> **Este é o único motor.** A antiga tela de *Alertas* (que só sabia mandar mensagem)
> foi **removida** — tudo que ela fazia, o Motor de Regras faz e muito mais: aqui
> "notificar" é apenas **uma** das ações — a regra também **liga um aparelho, roda uma
> cena, ABRE UMA PORTA, arma/desarma o alarme**, publica no MQTT e chama uma URL.

---

## 1. Instalar (uma vez)

**Passo 1 — Criar as tabelas.** No servidor, abra o phpMyAdmin (ou o cliente do
MariaDB), escolha o banco `controle_veiculos` e rode o arquivo:

```
api/database/migration_regra.sql
```

✅ **Deu certo se…** aparecerem as tabelas `regra`, `regra_estado`, `regra_fila` e
`regra_log` na lista.

**Passo 2 — Agendar o worker.** O motor precisa de um programinha rodando de minuto
em minuto (é ele que cuida de horário, sol, sensores e das ações com atraso).
Clique com o **botão direito** em `api\scripts\install_workers.bat` →
**"Executar como administrador"**.

✅ **Deu certo se…** ao final aparecer `[PRESENTE] auto_regras` na conferência.

**Passo 3 — Ligar o módulo.** No Nexus, vá em **Configurações → Módulos** e deixe
**"Motor de regras (SE → ENTÃO)"** ligado.

✅ **Deu certo se…** o menu **Automação → Regras** abrir sem erro.

---

## 2. O jeito mais rápido: começar de um modelo

Ao clicar em **+ Nova regra**, o primeiro cartão é **"✨ Começar de um modelo"**.
Escolha um modelo pronto na lista (ex.: *"Ao anoitecer, acende a luz"*, *"Caixa
d'água baixa"*, *"Dispositivo offline → avisa e abre OS"*, *"Ninguém em casa → arma
o alarme"*) e clique em **"Usar este modelo"**.

O formulário inteiro é preenchido para você. Só falta:

1. **Escolher o alvo** — o dispositivo, a porta ou a central de alarme (o modelo
   deixa em branco de propósito, porque só você sabe qual é).
2. **Conferir a mensagem** (se houver) — veja a **prévia** logo abaixo dela.
3. Clicar em **Salvar regra**.

> ⚠️ **Nada é criado enquanto você não salva.** O modelo só preenche a tela.

---

## 3. Variáveis nas mensagens (texto que se completa sozinho)

Nas ações de **Notificar** (e também na OS, no MQTT e no webhook), o texto pode ter
**variáveis** entre chaves — o sistema troca pelo valor real na hora do disparo.

Exemplo de mensagem: `Alerta! {dispositivo} está offline há {horas} h` vira
**"Alerta! Bomba da cisterna está offline há 1,5 h"**.

Você **não precisa decorar** os nomes: no editor, logo abaixo das ações, aparecem
**botões cinza** com as variáveis daquele gatilho (`{pessoa}`, `{dispositivo}`,
`{minutos}`, `{valor}`, `{central}`…). **Clique num botão** e ele insere a variável
no último campo de texto que você usou. A **prévia** mostra na hora como a mensagem
vai ficar (com valores de exemplo).

Algumas variáveis úteis por gatilho:

| Gatilho | Variáveis |
|---|---|
| Sempre (qualquer regra) | `{hora}` `{data}` `{data_hora}` `{regra}` |
| Acesso / passagem | `{pessoa}` `{placa}` `{ponto}` `{dispositivo}` `{acesso}` |
| Dispositivo offline | `{dispositivo}` `{minutos}` `{horas}` `{degrau}` |
| Sensor / medidor | `{valor}` `{nome}` (nome do aparelho/medidor) |
| Alarme | `{central}` `{descricao}` `{codigo}` `{zona}` `{particao}` |
| Clima | `{temp}` `{chuva}` `{vento}` `{aviso}` |

> Se uma variável não existir naquele gatilho, ela simplesmente sai **vazia** — não
> quebra a mensagem.

---

## 4. Os quatro exemplos, passo a passo

### Exemplo 1 — "Acesso liberado no leitor da garagem abre o portão social"

1. **Automação → Regras → + Nova regra**. Nome: `Garagem libera portão social`.
2. **SE (gatilho)** → escolha **Acesso / passagem**.
   - *Origem*: `InControl (facial/cartão)`
   - *Resultado*: `LIBERADO`
   - *Dispositivo InControl (contém)*: escreva um pedaço do nome do leitor, ex.: `Garagem`
3. **ENTÃO** → ação **Abrir porta / chave / portão** → escolha o **Portão Social**.
4. Salvar.

> **Como o sistema sabe se foi "liberado"?** O InControl não manda um campo
> "liberado/negado" — vem no **texto** do evento (`detalhe`). O Nexus lê esse texto
> e deduz o resultado. Se no seu equipamento o texto for diferente, use o campo
> **"Detalhe do evento (contém)"** e escreva a palavra que aparece de verdade
> (você vê os textos reais em **Portaria → Eventos**).

### Exemplo 2 — "Uma hora depois do pôr do sol, acende as luzes e libera uma porta"

1. Nova regra. Nome: `Anoiteceu`.
2. **SE** → **Nascer / pôr do sol**.
   - *Evento*: `Pôr do sol` · *Deslocamento*: `60` (minutos)
3. **ENTÃO** → três ações:
   - **Ligar/desligar dispositivo** → `Luz do jardim` → `Ligar`
   - **Executar cena** → `Iluminação noturna` (se você tiver uma cena pronta)
   - **Abrir porta / chave** → a porta desejada
4. Salvar.

> Depende do worker `auto_sun` (que calcula o nascer/pôr do sol 1x por dia) — ele já
> vem no instalador.

### Exemplo 3 — "No horário X: apaga uma luz, acende outra, abre a porta e avisa"

1. Nova regra. Nome: `Rotina das 22h`.
2. **SE** → **Horário**. *Hora*: `22:00`. Marque os *dias da semana* (ou deixe todos).
3. **ENTÃO** → quatro ações:
   - **Dispositivo** → `Luz da piscina` → `Desligar`
   - **Dispositivo** → `Luz do corredor` → `Ligar`
   - **Abrir porta / chave** → a porta desejada
   - **Notificar** → canais `Pushover` + `WhatsApp`, destino `Padrão global`,
     mensagem: `Rotina das 22h executada.`
4. Salvar.

> **Dica do atraso:** quer que a luz do corredor apague sozinha 10 minutos depois?
> Adicione uma 5ª ação (`Luz do corredor` → `Desligar`) e ponha **Atraso = 600**
> segundos. Ela entra numa fila e o worker executa na hora certa.

### Exemplo 4 — "Alerta climático vai para o WhatsApp dos moradores"

1. Nova regra. Nome: `Aviso de tempestade`.
2. **SE** → **Clima**.
   - Marque **"Tem aviso da Defesa Civil / INMET"**, e/ou preencha
     *Chuva prevista ≥* (ex.: `30` mm) e *Vento ≥* (ex.: `60` km/h).
3. **ENTÃO** → ação **Notificar**:
   - *Canais*: marque **WhatsApp** (e **Web Push**, se quiser)
   - *Destino*: **TODOS os moradores**
   - *Mensagem*: `Atenção: {aviso}. Recolha objetos soltos e evite sair.`
4. Salvar.

> O destino **"TODOS os moradores"** manda para cada pessoa cadastrada como
> *morador*, **ativa** e **com telefone**. Exige o WhatsApp (Z-API) configurado em
> **Configurações → Parâmetros**.

---

## 5. Testar sem esperar

Na lista de regras, o botão **▶** executa a regra **agora**, ignorando o cooldown.
⚠️ **As ações acontecem de verdade** (a porta abre mesmo). Depois, veja o resultado
em **Histórico** — ele mostra o que disparou **e o que NÃO disparou (e por quê)**.

---

## 6. Freios de segurança

- **Pausar o motor** (botão no topo de `/regras`): nenhuma regra dispara, nem as
  ações já agendadas. Use em manutenção.
- **Pausar uma regra só**: botão "Pausar" na linha dela.
- **Cooldown**: tempo mínimo entre dois disparos da mesma regra (evita que um
  sensor oscilando fique abrindo o portão sem parar).
- **Borda, não repetição**: gatilhos de sensor/clima/presença disparam quando
  **entram** na condição — não a cada minuto enquanto ela durar. Quando o valor sai
  da condição, a regra "re-arma" sozinha.
- Uma ação que falha **não impede as seguintes** (a porta abre mesmo se o WhatsApp
  estiver fora do ar) — e a falha aparece no histórico.

---

## 7. Deu problema?

**"A regra não dispara."**
Veja o **Histórico**: se aparecer `Condição não bateu`, o gatilho aconteceu mas uma
condição extra barrou. Se não aparecer NADA, o gatilho não aconteceu — confira o
worker em **Sistema → Diagnóstico** (procure `Motor de regras`).

**"Horário/sol/sensor não funcionam, mas acesso funciona."**
Esses dependem do worker `auto_regras` (1 min). Rode o `install_workers.bat` como
administrador e confira se `auto_regras` aparece no Agendador de Tarefas.

**"O gatilho de pôr do sol nunca dispara."**
Falta o worker `auto_sun` ter rodado hoje (ele preenche a tabela `auto_sun`). Ele
roda 1x/dia às 01:00.

**"A regra do InControl não sabe se foi liberado."**
Use o campo **"Detalhe do evento (contém)"** com a palavra exata que aparece em
**Portaria → Eventos** para o seu equipamento.

**"O MQTT não dispara."**
O gatilho MQTT exige o worker `mqtt_bridge` rodando e o módulo MQTT ligado.
