Voltar para o Blog

Conectando PHP à Automação Industrial com OPC UA

PT 🇧🇷Artigo6 min de leitura
#PHP#OPC UA#Automação Industrial#Laravel#Symfony

Você já se deparou com o desafio de integrar uma aplicação PHP moderna ao complexo mundo da automação industrial? Por anos, essa foi uma verdadeira dor de cabeça para muitos engenheiros. A boa notícia é que um novo ecossistema open-source está mudando completamente esse cenário.

O Problema: PHP e a Automação Industrial

O PHP domina cerca de 77% dos sites com linguagem de servidor conhecida — mas quando o assunto é automação industrial, a linguagem historicamente ficou de fora. PLCs (Controladores Lógicos Programáveis), sistemas SCADA e sensores IoT sempre "falaram" protocolos proprietários como Modbus, Profibus ou OPC DA, deixando desenvolvedores PHP sem opções nativas viáveis.

O resultado prático? Equipes forçadas a:

O que é OPC UA e Por Que Ele Muda o Jogo

OPC UA (Open Platform Communications Unified Architecture) é um padrão de comunicação industrial aberto, independente de plataforma, desenvolvido pela OPC Foundation. Diferente de seus predecessores, o OPC UA:

Em termos práticos, o OPC UA expõe um servidor com um espaço de endereçamento de nós (NodeSpace) que representa sensores, atuadores e variáveis do processo. Um cliente pode se conectar, ler valores, escrever comandos e assinar eventos em tempo real — tudo via protocolo padronizado.

open62541 + PHP: A Combinação que Faltava

A biblioteca open62541 é uma implementação C open-source e certificada do OPC UA. A partir dela, surgiu o php-opcua, uma extensão PHP que expõe os bindings nativos da biblioteca para o PHP userland.

Instalando a extensão

# Instalar open62541 (Ubuntu/Debian)
sudo apt-get install libopen62541-dev

# Clonar e compilar a extensão PHP
git clone https://github.com/php-opcua/php-opcua
cd php-opcua
phpize && ./configure && make && sudo make install

# Habilitar no php.ini
echo "extension=opcua.so" >> /etc/php/8.2/cli/php.ini

Conectando ao servidor OPC UA

<?php

$client = new OpcUa\Client();
$client->setEndpointUrl('opc.tcp://192.168.1.100:4840');
$client->setTimeout(5000);

// Conectar com autenticação anônima (produção deve usar certificados)
$client->connect();

// Leitura de um nó — temperatura do forno
$nodeId = OpcUa\NodeId::fromString('ns=2;s=Forno.Temperatura');
$value = $client->readValue($nodeId);

echo "Temperatura atual: " . $value->value . " °C\n";

$client->disconnect();

Integração com Laravel: Um Exemplo Real

A integração mais poderosa acontece quando você encapsula o cliente OPC UA dentro de um Service do Laravel, permitindo consultas dentro de jobs, controllers e eventos.

<?php

namespace App\Services;

use OpcUa\Client;
use OpcUa\NodeId;
use Illuminate\Support\Facades\Cache;

class PlcReaderService
{
    private Client $client;
    
    private string $endpoint;
    
    public function __construct(string $endpoint = null)
    {
        $this->endpoint = $endpoint ?? config('opcua.endpoint');
        $this->client = new Client();
    }

    public function connect(): void
    {
        $this->client->setEndpointUrl($this->endpoint);
        $this->client->connect();
    }

    public function readNode(string $nodeString, int $cacheTtl = 5): mixed
    {
        $cacheKey = "opcua:{$nodeString}";
        
        return Cache::remember($cacheKey, $cacheTtl, function () use ($nodeString) {
            $nodeId = NodeId::fromString($nodeString);
            $variant = $this->client->readValue($nodeId);
            return $variant->value;
        });
    }
    
    public function writeNode(string $nodeString, mixed $value): bool
    {
        $nodeId = NodeId::fromString($nodeString);
        return $this->client->writeValue($nodeId, $value);
    }

    public function disconnect(): void
    {
        $this->client->disconnect();
    }
}

Usando em um Controller

<?php

namespace App\Http\Controllers\Api;

use App\Services\PlcReaderService;
use Illuminate\Http\JsonResponse;

class TelemetryController extends Controller
{
    public function __construct(private PlcReaderService $plc)
    {
        $this->plc->connect();
    }

    public function dashboard(): JsonResponse
    {
        return response()->json([
            'temperatura' => $this->plc->readNode('ns=2;s=Forno.Temperatura'),
            'pressao'     => $this->plc->readNode('ns=2;s=Forno.Pressao'),
            'rpm_motor'   => $this->plc->readNode('ns=2;s=Motor.RPM'),
            'status'      => $this->plc->readNode('ns=2;s=Linha.Status'),
        ]);
    }
}

Subscriptions: Dados em Tempo Real com WebSockets

Uma das funcionalidades mais poderosas do OPC UA é o mecanismo de subscriptions: em vez de fazer polling, o cliente registra interesse em nós específicos e recebe notificações quando os valores mudam.

Combinado com Laravel Reverb ou Pusher, isso permite dashboards industriais em tempo real:

<?php

// Job que roda em background e publica eventos via WebSocket
class OpcUaSubscriberJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue;

    public function handle(PlcReaderService $plc): void
    {
        $plc->connect();
        
        $subscription = $plc->createSubscription(publishingInterval: 500); // ms
        
        $subscription->addMonitoredItem('ns=2;s=Forno.Temperatura', function ($value) {
            broadcast(new TemperaturaAtualizada($value));
        });
        
        $subscription->run(maxIterations: 1000);
    }
}

Desafios Comuns e Como Resolvê-los

1. Latência e Timeouts

Redes industriais nem sempre são estáveis. Implemente retry com backoff exponencial:

$maxRetries = 3;
$attempt = 0;

while ($attempt < $maxRetries) {
    try {
        $value = $plc->readNode($nodeString);
        break;
    } catch (\OpcUa\ConnectionException $e) {
        $attempt++;
        sleep(2 ** $attempt); // 2s, 4s, 8s
        $plc->connect(); // Reconectar
    }
}

2. Segurança em Ambientes de Produção

Nunca use autenticação anônima em produção. Configure certificados X.509:

$client->setSecurityMode(OpcUa\SecurityMode::SIGN_AND_ENCRYPT);
$client->setCertificate('/path/to/client.crt');
$client->setPrivateKey('/path/to/client.key');
$client->setTrustList('/path/to/trusted/');

3. Mapeamento de Tipos

Os tipos OPC UA (Float, Int32, Boolean, DateTime) precisam ser mapeados para tipos PHP. A extensão faz isso automaticamente, mas fique atento a valores nulos (BadNoData) que indicam falha no sensor.

FAQ

Q: Preciso instalar o open62541 em todos os servidores? A: Sim. A extensão PHP é um wrapper C, então a biblioteca nativa precisa estar presente. Em ambientes Docker, basta incluir no Dockerfile. Em produção com Kubernetes, use uma imagem base customizada.

Q: É possível usar OPC UA com PHP no Windows (IIS)? A: Tecnicamente sim — open62541 compila no Windows — mas a maioria dos deployments industriais usa Linux. O overhead de configuração no IIS raramente vale a pena.

Q: O OPC UA substitui completamente o SCADA? A: Não. O OPC UA é um protocolo de comunicação, não um sistema SCADA completo. Ele habilita que sua aplicação PHP leia e escreva nos mesmos dados que o SCADA acessa, criando uma integração complementar.

Conclusão

A chegada de extensões PHP maduras para OPC UA remove uma barreira histórica entre o mundo web e o chão de fábrica. O que antes exigia middlewares proprietários caros agora pode ser resolvido com Laravel ou Symfony, frameworks que sua equipe já domina.

Se você está construindo dashboards de telemetria, sistemas MES (Manufacturing Execution System) ou integrações IoT, vale muito a pena explorar esse ecossistema open-source. O custo de adoção caiu dramaticamente — e a qualidade da integração nunca foi tão boa.

Newsletter

Fique à frente da curva

Insights técnicos aprofundados sobre arquitetura de software, IA e engenharia. Sem enrolação. Um e-mail por semana.

Sem spam. Cancele quando quiser.

Conectando PHP à Automação Industrial com OPC UA | Antonio Ferreira