QUESTÃO 7 - DIRCURSIVA

CAPACIDADE: Demonstrar fluxo de automação.

Contexto:

No projeto RNC foi desenvolvido uma lógica de controle entre CLP e Node-RED que tem como objetivo gerenciar e monitorar as inserções e buscas de dados na base SQLite.

Comando:

Explique como o handshake entre CLP e Node-RED garante integridade e sincronismo dos dados no projeto RNC.

Passo 1

O que o enunciado pede:
  • Explicar como o handshake entre o CLP e o Node-RED garante integridade e sincronismo dos dados no projeto RNC.
Informações fornecidas pelo enunciado:
  • Existe uma lógica de controle entre CLP e Node-RED.
  • Essa lógica tem como objetivo gerenciar e monitorar inserções e buscas de dados em uma base SQLite.
  • O foco é o mecanismo de handshake (troca controlada de mensagens) entre CLP e Node-RED.
O que vou fazer nos próximos passos:
  • Mostrar, passo a passo, o que é um handshake, que informações a mensagem deve carregar, como confirmar recepção, como garantir integridade (sem corromper dados) e como manter sincronismo (ordem e consistência entre CLP e banco).
  • Apresentar técnicas concretas (sequência, checagem de integridade, ACK/COMMIT, transações SQLite, tratamento de falhas, idempotência, heartbeats).
  • Dar exemplos práticos de fluxo de mensagens e de como montar a lógica no Node-RED (conceitual, em linguagem acessível).

Passo 2

O que é handshake e por que ele importa aqui (visão simples e direta)
  • Handshake é a sequência combinada de mensagens entre dois pontos para combinar “quem faz o quê, quando e com que confirmação”. É como bater palma duas vezes para combinar que ambos estão prontos antes de começar uma dança.
  • No nosso caso, handshake garante duas coisas essenciais:
    1. Integridade: a mensagem enviada pelo CLP foi recebida sem alteração e foi registrada corretamente no SQLite.
    2. Sincronismo: o CLP sabe se a operação foi efetivamente gravada e em que ordem, evitando duplicidade ou perda de comando.

Passo 3

Estrutura mínima de uma mensagem de handshake — o que cada campo significa (use isso na prova)
  • Uma mensagem de escrita do CLP para Node-RED (esqueleto JSON conceitual):
    • id_origem: identificação do CLP (ex.: “CLP1”)
    • seq: número sequencial da operação ( \text{seq})
    • tipo: “write” / “read” / “commit” / “heartbeat”
    • payload: dados a gravar (valores, tags, etc.)
    • ts: timestamp do CLP (opcional, ajuda no debug)
    • checksum: soma de verificação (ex.: CRC32) do payload e cabeçalho
  • Explicação dos campos:
    • \text{seq}: controla a ordem e detecta duplicatas/retransmissões.
    • checksum: detecta corrupção na transmissão.
    • ts: ajuda a ordenar eventos quando há pequenas discrepâncias de tempo.

Passo 4

ACK / NACK e confirmação de commit: como o handshake efetivamente confirma a gravação
  • Fluxo básico proposto:
    1. CLP envia: \{\text{id_origem}, \text{seq}, \text{tipo}=\text{write}, \text{payload}, \text{checksum}\}.
    2. Node-RED valida checksum; se inválido responde NACK (com \text{seq} e motivo).
    3. Se válido, Node-RED inicia uma transação SQLite, grava dados (incluindo \text{seq} e metadados) e tenta COMMIT.
    4. Se commit OK, Node-RED responde ACK+COMMIT: \{\text{seq}, \text{status}=\text{committed}, \text{db_ts}\}.
    5. Se o commit falhar, Node-RED responde NACK+erro; CLP pode retransmitir ou alertar operador.
  • Por que isso garante integridade/sincronismo:
    • O CLP só considera a operação concluída quando recebe ACK de commit.
    • O Node-RED só confirma após a transação SQLite ter sido realmente comitada (garantia ACID).

Passo 5

Sequência, idempotência e detecção de duplicatas (para evitar gravar duas vezes)
  • Problema comum: CLP retransmite por timeout e o Node-RED já gravou a primeira vez → duplicidade.
  • Solução: usar \text{seq} e chave única no banco.
    • No esquema SQLite, gravar campo \text{source} (id_origem) e \text{seq} com constraint UNIQUE:
      • INSERT … ON CONFLICT IGNORE (ou checar antes).
    • Quando receber uma mensagem com \text{seq} já existente, Node-RED responde ACK imediata com “already committed” sem regravar.
  • Isso torna a operação idempotente: retransmissões não alteram o estado além da primeira gravação.

Passo 6

Checksum, assinaturas e integridade do payload
  • Checksum simples (CRC32/MD5) detecta corrupção durante a transmissão.
  • Processo:
    • CLP calcula checksum do payload+cabecalho e envia.
    • Node-RED recalcula; se diferente, informa NACK e ignora.
  • Se for necessário maior nível de segurança, usar HMAC com chave compartilhada para detectar manipulação maliciosa (HMAC-SHA256).
  • Importante: checksum protege a integridade da mensagem, não a durabilidade do dado no banco — por isso a confirmação de commit é obrigatória.

Passo 7

Como usar transações SQLite para garantir atomicidade e durabilidade
  • Princípios SQLite úteis na prova (palavras simples):
    • Começar transação: BEGIN TRANSACTION
    • Fazer INSERT/UPDATE/DELETE
    • Finalizar: COMMIT (tudo foi gravado) ou ROLLBACK (volta ao estado anterior se erro)
  • No Node-RED:
    • Ao receber mensagem válida, abrir transaction, executar statement(s) e só enviar ACK ao CLP após COMMIT bem-sucedido.
  • Configurações importantes (durante implantação ou prova):
    • PRAGMA journal_mode = WAL (melhora concorrência e recuperação)
    • PRAGMA synchronous = FULL (garante escrita segura no disco, com custo de latência) — escolha conforme trade-off entre performance e segurança.
    • busy_timeout: para evitar “database is locked” em concorrência.
  • Explicação didática: transação é o ato de agrupar operações em “tudo ou nada”; o ACK só sai quando o “tudo” foi efetivado no disco.

Passo 8

Ordenação, clocks e resolução de conflitos (sincronismo entre eventos)
  • Ordem: \text{seq} principal para garantir ordenação por origem.
  • Cross-origin ordering (vários CLPs): incluir timestamp \text{ts} e uma chave composta (\text{id_origem},\text{seq}). Para ordenação global, usar um campo de “inserção no DB” (ex.: AUTOINCREMENT rowid ou timestamp do Node-RED).
  • Clocks: sincronizar relógio dos CLPs e servidor Node-RED via NTP para evitar confusões com timestamps.
  • Conflitos: se two CLPs escreverem a mesma entidade, solução de aplicação:
    • estratégia last-writer-wins (usar timestamp confiável)
    • ou estratégia de merge / versionamento (cada registro tem version number e operações que não batem são rejeitadas com NACK para o CLP resolver)

Passo 9

Tratamento de falhas, reconexão e mecanismos de reentrega
  • Timeout e retransmissão: CLP reenvia se não receber ACK em timeout T. Escolher T considerando latência da rede e operação de gravação no DB.
  • Fila persistente no CLP: manter operações não confirmadas em buffer persistente até receber ACK; evita perda por reinício.
  • Buffer persistente no Node-RED (context.persist): caso Node-RED reinicie antes de ACK, manter estado das operações pendentes e ao reiniciar completar commits pendentes ou responder NACK/ACK conforme situação.
  • Estratégia de backoff exponencial para reconexões (evita flood).
  • Monitor e alarme: gerar alerta se número de retransmissões por segundo ultrapassar threshold.

Passo 10

Como mapear handshake para protocolos comuns (opções práticas)
  • Modbus TCP / RTU: já é request-response; usar função write e só confirmar quando Node-RED gravar no DB. Pode encapsular seq no payload.
  • MQTT: usar QoS:
    • QoS 1 (at least once) + idempotência no DB (seq ou unique key) → evita duplicatas.
    • QoS 2 (exactly once) fornece mais garantia, mas mais complexidade.
    • Usar tópicos de resposta (reply-to) para ACK/COMMIT.
  • HTTP/REST: CLP faz POST; Node-RED responde 200 OK após commit; em caso de timeout CLP reenvia.
  • OPC UA: tem serviços e confirmações; combinar a confirmação do servidor com commit DB.
  • Observação didática: escolha baseada em hardware/stack do CLP; mas os princípios do handshake são os mesmos.

Passo 11

Implementação prática (padrão de fluxo no Node-RED) — ideais para a prova
  • Node-RED flow sugerido (conceito):
    1. entrada (MQTT in / TCP in / Modbus node / HTTP in)
    2. function node: validar formato, calcular/checar checksum, extrair \text{seq} e meta
    3. function node: checar duplicata (query SQLite: existe (\text{id_origem},\text{seq})?)
      • se existe → enviar ACK “already committed”
      • se não existe → ir para transação
    4. sqlite node (ou function que chama sqlite3): BEGIN; INSERT registro com \text{seq}; COMMIT
    5. em caso de COMMIT OK → enviar ACK/COMMIT ao CLP
    6. em caso de erro → ROLLBACK; logar; enviar NACK com código de erro
    7. opcional: enviar evento para dashboard/alerta
  • Dicas de implementação:
    • guardar logs de cada etapa (recebido, validado, insert attempted, committed)
    • usar context persistente para estado entre reinícios
    • definir tempo de espera e políticas de retry do CLP

Passo 12

Exemplo concreto e passo-a-passo da troca (para memorização durante prova)
  • Exemplo de mini-handshake para uma escrita:
    1. CLP -> Node-RED:
      {
      “id_origem”:“CLP1”,
      “seq”: \,45\,,
      “tipo”:“write”,
      “payload”:{“tag”:“nivel”,“valor”:2,34},
      “ts”:“2025-11-30T10:00:00Z”,
      “checksum”:“0xA3B2C1D4”
      }
    2. Node-RED recalcula checksum → OK.
    3. Node-RED checa se ( "CLP1",45) existe no DB → não existe.
    4. Node-RED faz:
      • BEGIN TRANSACTION
      • INSERT into leituras (id_origem, seq, tag, valor, ts_node) VALUES (…)
      • COMMIT
    5. Node-RED -> CLP: { “seq”: \,45\,, “status”:“committed”, “db_ts”:“2025-11-30T10:00:01Z” }
    6. CLP marca seq \,45\, como entregue e passa ao próximo comando.
  • Se o CLP não receber resposta, reenvia \,45\, até receber ACK; Node-RED, ao receber duplicate \,45\,, responde ACK sem regravar.

Passo 13

Checklist de boas práticas (resumo rápido para anotar antes da prova)
  • Sempre ter \text{seq} por origem e UNIQUE no DB.
  • Usar checksum/HMAC no payload.
  • ACK só após COMMIT SQLite.
  • Usar transações (BEGIN/COMMIT/ROLLBACK).
  • Configurar PRAGMA adequados (WAL, synchronous conforme necessidade).
  • Implementar fila persistente e retry no CLP.
  • Heartbeat/keepalive para detectar desconexões.
  • Logs e monitoramento para detectar falhas ou degradação.
  • Testes de recuperação (reinício do Node-RED, perda de rede, power cycle do CLP).

Resposta

O handshake garante integridade e sincronismo combinando: mensagens com número sequencial ( \text{seq}) e checksum/HMAC para detectar corrupção; confirmação (ACK) enviada pelo Node-RED somente após a transação SQLite ser COMMITada (garantia ACID); detecção de duplicatas via chave única (\text{id\_origem},\text{seq}) para tornar operações idempotentes; timeout/retry e fila persistente no CLP para reenvio seguro; heartbeats e sincronização de relógios para ordenação e detecção de falhas; e políticas de rollback/alerta para recuperar ou notificar em caso de erro. Juntos, esses elementos asseguram que cada comando do CLP seja validado, gravado de forma atômica e reconhecido, mantendo os dados íntegros e sincronizados entre CLP, Node-RED e a base SQLite.

Exercícios relacionados