Caso de engenharia
CORTEX
A plataforma industrial que substituiu o supervisório legado de oito plantas
Oito plantas mediam produção e parada com um supervisório de uma geração anterior. O número que chegava à diretoria era produzido por lógica em VBA, gravado em arquivo sobre compartilhamento de rede, e estava errado. Este é o relato de como ele foi refeito sem a fábrica parar um minuto para isso.
- Papel
- Arquitetura e desenvolvimento, sozinho
- Ambiente
- Indústria em operação contínua
- Estado
- Em produção nas oito plantas
- Restrição central
- Toda interação com controlador é leitura
A régua
Números medidos na própria plataforma, não estimados.
- 529equipamentos com estado ao vivoeram 84
- 8plantas na mesma baseeram oito ilhas
- 95 milregistros de métrica por dia
- 219migrações versionadascada uma com a volta escrita
- 68routers na API
- 13unidades implantáveisweb, desktop, coletores
O problema não era a tela, era a origem
O pedido que chega costuma ser um relatório. Aqui ele chegou como telão: a diretoria queria ver ociosidade, e ociosidade ninguém media. O que existia era um indicador de disponibilidade publicado num painel, alimentado por uma cadeia que ninguém tinha auditado inteira.
A cadeia era esta: lógica em VBA dentro das telas do supervisório, gravação em arquivos sobre compartilhamento de rede, um banco sem réplica, e cada planta como uma ilha, sem histórico comparável com a vizinha. De cerca de 773 equipamentos, apenas 84 tinham estado visível ao vivo.
O número que existia não era confiável, e isso é pior do que não ter número. Sem número, a decisão espera. Com número errado, a decisão acontece do mesmo jeito.
A restrição que desenhou tudo
Fábrica não para para ser testada. Essa frase não é retórica de projeto, é a regra que define o que pode ser construído: toda interação com controlador é leitura, e escrita existe apenas como fila auditada com lista de permissão. Ligar e desligar equipamento ficaram barrados por decisão de projeto, não por falta de tempo de implementar.
A consequência prática aparece em cada escolha adiante. Não dá para descobrir como o sistema se comporta provocando o sistema. Sobra observar, medir e provar com o que já está acontecendo.
Provar antes de comprar
O serviço de navegação do controlador listava 84 equipamentos instrumentados. Quem confiasse nisso concluiria que o resto da fábrica precisava de sensor novo, e a conta iria para a diretoria com esse tamanho.
Em vez de confiar na listagem, escrevi um enumerador que deriva o endereço de cada variável a partir da convenção da engenharia e testa candidato por candidato contra o controlador. Nada entrou no catálogo por dedução: entrou porque respondeu.
A sondagem tinha uma armadilha que quase a invalidou. A leitura em lote devolve vazio tanto para endereço inexistente quanto para endereço sem valor no momento, então ela passa inteira verde e mente. Para provar ausência foi preciso ler o status de cada nó, um a um.
ResultadoOs 84 equipamentos viraram 529, com 2.016 variáveis verificadas, dentro do teto de sessões do hardware. E a contraprova valeu tanto quanto: nos silos a mesma sondagem mostrou que nível contínuo não existe em nenhum deles, só contato de baixo, alto e cheio. Foi isso que separou o que era falha de cadastro do que era compra de instrumento.
O indicador que publicava 2.627%
Uma extrusora em reforma aparecia no telão como 98,3% disponível. A consulta derivava parada comparando cada evento do log com o seguinte, sem teto e sem recorte por dia: um segmento que nunca fechou somou 618 horas corridas e caiu inteiro num único dia do relatório.
Junto vinha um erro mais sutil, e mais perigoso, porque parecia certo. O bit de ligado do controlador quer dizer painel energizado, não motor girando. Um equipamento apareceu 6,4 dias ligado, atravessando um fim de semana de fábrica fechada, com a corrente do motor em 0,0 A o tempo todo.
Houve também uma correção que não é de código. O indicador deixou de se chamar OEE e passou a se chamar disponibilidade, porque performance e qualidade nunca foram medidas. Chamar de OEE o que não é OEE é inventar dado com nome respeitável.
ResultadoDisponibilidade publicada: 35,7% virou 26,9%. Horas de produção: 21.748 h viraram 18.782 h. Todas as correções derrubaram números. Entregar um número menor e correto a quem já usava o maior só funciona com a evidência junto, e por isso cada uma virou decisão escrita, com problema, razão e resultado.
Onde colocar o limiar entre parado e girando em vazio
Uma extrusora acumulava 198 horas de ociosidade em 30 dias, alto demais para ser verdade. Nove dos 39 intervalos batiam exatamente 12,00 h, que é de quanto em quanto tempo o coletor fechava janela, e caíam em fim de semana de fábrica fechada.
O limiar que separa motor parado de motor girando em vazio não veio de palpite nem de arredondamento: veio do fundo do vale do histograma bimodal de corrente elétrica, que é onde os dois estados se separam fisicamente.
Registrei também a armadilha metodológica que quase usei. Dizer que um limiar acima do percentil 10 indica falso positivo é raciocínio circular: usa como referência exatamente a distribuição que está sob suspeita.
ResultadoQueda de 57% naquele equipamento e de 42% a 62% nos demais. No conjunto, 229,7 h viraram 162,1 h depois de calibrar. Ficou uma regra para o projeto inteiro: a saúde de uma rotina se mede pelo carimbo do dado mais recente que ela produziu, nunca pelo log dela. Teve rotina imprimindo ok, zero linhas por 44 dias, e container no ar, zero reinícios, com metade do caminho morto havia 65.
A tela que só sabia dizer ligado ou desligado
A linha do tempo de um equipamento pintava dois estados. Parecia completa e não era: falha e manutenção chegavam do chão de fábrica e eram descartadas no meio do caminho, então uma parada por defeito aparecia com a mesma cor de um equipamento fora de turno.
Todos os estados passaram a chegar até a tela, cada um com a própria duração, mais o estado que faltava e que é o mais honesto de todos: sem informação. A falha deixou de ser um número e virou frase em português, com causa provável, ação sugerida e severidade.
Onde o acionamento publica a palavra de estado, ela é decodificada e mostrada ao vivo, com um aviso explícito na própria tela: o bit de falha diz que existe falha, não qual é.
ResultadoEm sete dias de um único equipamento apareceram 2,97 h em falha, em seis eventos que antes ficavam escondidos dentro do cinza de desligado. O código de falha do fabricante estava ausente em 100% dos eventos gravados, e a resposta a isso foi registrar o instante e pedir apontamento humano com procedência, em vez de exibir um código plausível e inventado.
Quando o identificador era, na verdade, um rótulo
Buscar por lote devolvia milhares de ordens. Medido: 108 códigos distintos cobriam 24.110 ordens em cinco anos, e o mais frequente aparecia 4.469 vezes, abrangendo 614 produtos diferentes.
O gerador antigo concatenava atributos que já tinham coluna própria, e nada ali garantia unicidade. Era um rótulo ocupando o lugar de um identificador, e ninguém tinha percebido porque o campo estava preenchido.
ResultadoFormato datado em padrão GS1, gerado por sequência atômica no banco, dimensionado para caber no campo que já existia, sem migração de tela. Se a geração falha, a ordem não nasce com lote inventado. Foram 24.028 ordens retroconvertidas sem uma única duplicata, com o código antigo preservado ao lado do novo para o histórico continuar pesquisável pelos dois.
Como está montado
Treze unidades implantáveis sobre um backend único. A divisão não é enfeite de arquitetura: cada peça sobe e volta sozinha, porque numa planta em operação não existe janela para subir tudo junto.
Coleta
Coletores em leitura estrita sobre OPC UA, com normalização e buffer. A lista de variáveis recarrega sozinha, então incluir equipamento novo não pede reinício.
Dados
SQL Server com 219 migrações versionadas, cada uma com o rollback escrito na mesma entrega. Em base de produção que não pode parar, poder voltar é o que autoriza avançar.
API
FastAPI com 68 routers sobre SQLAlchemy Core. SQL explícito e revisável no lugar de ORM de entidade, porque aqui a consulta é o produto e ela precisa ser lida por quem audita o número.
Supervisório web
Editor gráfico próprio, com símbolo, tubulação animada, vínculo de variável, alarme, replay histórico e a função que responde por que parou.
Chão de fábrica
Terminal em .NET que substitui o shell do Windows, com login por crachá, mais suporte remoto que entra na mesma sessão do operador, com permissão específica e conexão auditada.
Observabilidade
Pipeline declarativo de alarmes e vigilância própria. A regra aprendida na marra: medir a rotina pelo carimbo do dado que ela produziu, não pelo que ela escreve no log.
O que ainda está em aberto
Caso de engenharia sem lista de pendência é propaganda. Estas são as frentes que continuam abertas, com o tamanho real de cada uma.
- A decodificação de estado do acionamento cobre 8 equipamentos hoje. O levantamento do programa de um dos controladores mostrou 36 palavras de estado que existem e não são publicadas: publicá-las levaria a cobertura para 44. Depende de alteração no lado do controlador, que não é leitura, então não é uma decisão minha sozinha.
- O código de falha do fabricante continua ausente na origem. Enquanto ele não for publicado, a causa depende de apontamento humano, e apontamento humano falha em turno cheio.
- Um dos controladores segue sem levantamento atualizado do programa, então daquela linha eu sei menos do que sei das outras. Está escrito assim no projeto, e não arredondado para cima.
Tecnologia
Listada no fim de propósito. Ela é consequência das decisões acima, não o começo delas.
- Chão de fábricaOPC UA · CLP · IHM · inversor e soft-starter · corrente de motor
- ServiçosPython 3.12 · FastAPI · SQLAlchemy Core · Telegraf
- DadosSQL Server · T-SQL com funções de janela · migração versionada com rollback
- InterfaceReact 18 · Next.js 15 · editor gráfico próprio · C# .NET 8 com WPF
- OperaçãoDocker Swarm · observabilidade própria · decisões versionadas em markdown
O fio que atravessa tudo
Nenhum dos problemas acima era de código. Eram de origem do dado: uma listagem que omitia, um bit que significava outra coisa, um campo de data que era carimbo de inserção, um rótulo ocupando o lugar de identificador, um estado descartado antes da tela. Software não conserta isso, só publica mais rápido.
Por isso a régua do projeto virou uma frase: não sei não é a mesma coisa que sei que não há. Indicador nenhum sai sem denominador explícito, e quando o número corrigido é pior que o publicado, ele vai junto com a evidência que o justifica.