Arquitetura Detalhamento dos Módulos - ES2-UFPI/TermoLOG GitHub Wiki

Detalhamento dos Módulos

Os módulos seguem as camadas descritas na Visão Geral. As histórias de usuário citadas (US) estão nas issues do repositório. Os nomes dos componentes ainda podem mudar durante a implementação.

1. Firmware

1.1 Nó de borda

Roda em cada ESP32 com DHT22. Lê o sensor no intervalo configurado, compara com a faixa da sala, liga ou desliga o alarme local e envia a leitura para o nó central por LoRa/LoRaWAN. Entre uma leitura e outra fica em deep sleep para economizar bateria.

Histórias relacionadas: US01, US03, US21

1.2 Nó central

Recebe as leituras dos nós de borda por LoRa/LoRaWAN e envia em lote para a API por HTTPS. As leituras ficam numa fila até a API confirmar o recebimento, então nada se perde se a internet cair. A cada envio ele também pergunta à API se há configuração nova para algum nó (frequência de leitura ou faixa) e repassa por LoRa/LoRaWAN.

Histórias relacionadas: US01, US03

2. Backend (FastAPI)

Cada módulo é uma pasta com as rotas (router.py), as regras de negócio (service.py) e os modelos do banco (models.py).

2.1 Leituras

Recebe os lotes enviados pelo nó central, confere se o sensor existe e grava as leituras com data, hora e sala. Depois de gravar, chama o módulo de alertas para verificar a faixa.

Componentes previstos: LeituraService, Leitura

Histórias relacionadas: US01, US04

2.2 Salas e Sensores

Cadastro de salas e sensores. Cada sensor tem um ID único e fica vinculado a uma sala. Também guarda a faixa de temperatura e umidade de cada sala, a frequência de leitura e a data de calibração dos sensores.

Componentes previstos: SalaService, SensorService, Sala, Sensor

Histórias relacionadas: US02, US03, US04, US05, US11, US18

2.3 Alertas

Abre um alerta quando uma leitura sai da faixa da sala ou quando a sala fica sem enviar leituras. O alerta começa como pendente, passa a reconhecido quando alguém confirma no painel que viu (fica registrado quem e quando) e é encerrado quando a ação corretiva é registrada. Depois de encerrado não pode mais ser alterado.

Componentes previstos: AlertaService, Alerta

Histórias relacionadas: US07, US11, US12, US25, US26

2.4 Notificações

Envia o alerta pelos canais que cada usuário escolheu no perfil: e-mail, push, Telegram. Se o envio falhar em um canal, os outros continuam funcionando. Fora do horário comercial, o aviso vai para o contato de plantão.

Componentes previstos: NotificacaoService, CanalNotificacao, CanalEmail, CanalPush, CanalTelegram

Histórias relacionadas: US17, US20

Padrão aplicado: Strategy (ver seção 4)

2.5 Relatórios

Gera o relatório em PDF para a vigilância sanitária, com cabeçalho fixo (estabelecimento, sala, período e responsável técnico) e a tabela de leituras, e também o relatório de alertas com as ações corretivas. Além disso, exporta o histórico de uma sala em PDF, Excel ou CSV.

Componentes previstos: RelatorioService, Exportador, ExportadorPDF, ExportadorExcel, ExportadorCSV

Histórias relacionadas: US10, US15, US26

Padrão aplicado: Strategy (ver seção 4)

2.6 Usuários

Login com usuário e senha e controle de perfis. Só administradores podem alterar faixas, sensores e destinatários de alerta.

Componentes previstos: AuthService, UsuarioService, Usuario

Histórias relacionadas: US14, US24

3. Dashboard web (React + TypeScript)

Segue a estrutura do tutorial de React, com as pastas pages, components, hooks e services. Telas previstas:

  • Painel: todas as salas com temperatura, umidade e status, destacando as que estão fora da faixa (US09, US19);
  • Sala: gráfico do histórico com a faixa ideal marcada e botão de exportar (US15, US16);
  • Alertas: pendentes e reconhecidos separados, com a opção de reconhecer e registrar a ação corretiva (US12, US26);
  • Relatórios: geração do PDF por sala e período (US10);
  • Configurações: salas, sensores, faixas e canais de alerta (US03, US11, US17);
  • Login (US14).

4. Padrão de projeto

Strategy

Usado em dois pontos do backend: nas notificações e na exportação dos relatórios.

Na US17 o usuário escolhe por quais canais quer receber os alertas, e pode escolher mais de um. Cada canal envia de um jeito diferente (servidor SMTP no e-mail, via Telegram, serviço de push), mas para o módulo de notificações isso não importa: ele só precisa enviar o alerta. Por isso cada canal vira uma classe com o mesmo método enviar, e o serviço percorre os canais escolhidos pelo usuário.

class CanalNotificacao(ABC):
    @abstractmethod
    def enviar(self, usuario, alerta): ...

class CanalEmail(CanalNotificacao):
    def enviar(self, usuario, alerta):
        ...  # envio por SMTP

class CanalPush(CanalNotificacao):
    def enviar(self, usuario, alerta):
        ...  # envio de notificação push

CANAIS = {"email": CanalEmail(), "push": CanalPush()}

def notificar(usuario, alerta):
    for nome in usuario.canais:
        try:
            CANAIS[nome].enviar(usuario, alerta)
        except Exception:
            registrar_falha(alerta, nome)

Assim dá para começar só com e-mail e push e adicionar Telegram depois, criando uma classe para cada um, sem mexer na função notificar. O try dentro do laço atende o critério da US17 de que a falha em um canal não impede o envio pelos outros.

Na exportação (US15) a ideia é a mesma: o usuário escolhe PDF, Excel ou CSV, e cada formato é uma classe (ExportadorPDF, ExportadorExcel, ExportadorCSV) com o mesmo método exportar. O relatório monta os dados uma vez só, e quem decide o formato do arquivo é o exportador escolhido.