gianfriaur/opcua-laravel-client

This package is abandoned and no longer maintained. The author suggests using the https://github.com/php-opcua/laravel-opcua package instead.

Laravel integration for OPC UA client with optional session manager support

Maintainers

Package info

github.com/php-opcua/laravel-opcua

pkg:composer/gianfriaur/opcua-laravel-client

Statistics

Installs: 5

Dependents: 0

Suggesters: 0

Stars: 4

Open Issues: 0

v4.4.0 2026-05-28 12:23 UTC

This package is auto-updated.

Last update: 2026-06-09 16:16:51 UTC


README

OPC UA Laravel Client

Tests Coverage Latest Version PHP Version License Stars Laravel Version

Linux macOS Windows

Laravel integration for OPC UA built on opcua-client and opcua-session-manager. Connect your Laravel app to PLCs, SCADA systems, sensors, and IoT devices with a familiar developer experience: a Facade, .env-based configuration, named connections (like config/database.php), and an Artisan command for the optional session manager daemon.

What you get:

  • FacadeOpcua::read('i=2259') with full IDE autocompletion
  • Named connections — define multiple OPC UA servers and switch between them, just like database connections
  • Transparent session management — when the daemon is running, connections persist across HTTP requests; when it's not, direct per-request connections with zero code changes
  • Laravel-native logging and caching — your log channel and cache store are automatically injected into every OPC UA client
  • All OPC UA operations — browse, read, write, method calls, subscriptions, events, history, path resolution, type discovery
  • PSR-14 events — 47 dispatched events covering every OPC UA operation for observability and extensibility
  • Auto-publish — daemon monitors subscriptions automatically and dispatches PSR-14 events to your Laravel listeners — no manual publish loop
  • Auto-connect — define subscriptions in config/opcua.php per connection and the daemon sets them up at startup
  • Trust store — certificate trust management with configurable policies and auto-accept modes
  • Write auto-detection — omit the type parameter and let the client detect the correct OPC UA type automatically

Note: This package wraps the full opcua-client API with Laravel conventions. For the underlying protocol details, types, and advanced features, see the client documentation.

Tested against the OPC UA reference implementation

The underlying opcua-client is integration-tested against UA-.NETStandard — the reference implementation maintained by the OPC Foundation, the organization that defines the OPC UA specification.

This Laravel package is additionally integration-tested via uanetstandard-test-suite in both direct and managed (daemon) modes, ensuring full compatibility across all connection strategies. Like opcua-client and opcua-session-manager, unit tests run cross-OS — Linux, macOS, and Windows across PHP 8.2–8.5 × Laravel 11/12/13 — on every push. Integration tests stay on Linux (Docker-hosted OPC UA servers).

Runs on Linux, macOS, and Windows

The session manager IPC auto-selects the right transport per platform — zero app-side changes.

Platform Default transport Endpoint URI
Linux / macOS Unix-domain socket unix://<storage_path('app/opcua-session-manager.sock')>
Windows TCP loopback tcp://127.0.0.1:9990

config/opcua.php → session_manager.socket_path defaults to the platform-appropriate URI. Override by setting OPCUA_SOCKET_PATH in .env to either a unix://<path>, a tcp://127.0.0.1:<port> (loopback-only — non-loopback hosts are refused on both client and daemon sides), or a scheme-less path (= unix://<path>, backwards-compatible with pre-v4.2.0 configs).

Quick Start

composer require php-opcua/laravel-opcua
# RSA security (or use ECC: ECC_nistP256, ECC_nistP384, ECC_brainpoolP256r1, ECC_brainpoolP384r1)
OPCUA_ENDPOINT=opc.tcp://192.168.1.100:4840
use PhpOpcua\LaravelOpcua\Facades\Opcua;

$client = Opcua::connect();

$value = $client->read('i=2259');
echo $value->getValue(); // 0 = Running

$client->disconnect();

That's it. Facade, .env, connect, read. Everything else is optional.

See It in Action

Browse the address space

$client = Opcua::connect();

$refs = $client->browse('i=85'); // Objects folder
foreach ($refs as $ref) {
    echo "{$ref->displayName} ({$ref->nodeId})\n";
}

$client->disconnect();

Read multiple values with fluent builder

$client = Opcua::connect();

$results = $client->readMulti()
    ->node('i=2259')->value()
    ->node('ns=2;i=1001')->displayName()
    ->execute();

foreach ($results as $dv) {
    echo $dv->getValue() . "\n";
}

$client->disconnect();

Write to a PLC

use PhpOpcua\Client\Types\BuiltinType;

$client = Opcua::connect();
$client->write('ns=2;i=1001', 42, BuiltinType::Int32);

// Or let the client auto-detect the type
$client->write('ns=2;i=1001', 42);

$client->disconnect();

Call a method on the server

use PhpOpcua\Client\Types\Variant;
use PhpOpcua\Client\Types\BuiltinType;

$client = Opcua::connect();

$result = $client->call(
    'i=2253',   // Server object
    'i=11492',  // Method
    [new Variant(BuiltinType::UInt32, 1)],
);

echo $result->statusCode;               // 0
echo $result->outputArguments[0]->value; // [1001, 1002, ...]

$client->disconnect();

Subscribe to data changes

$client = Opcua::connect();

$sub = $client->createSubscription(publishingInterval: 500.0);
$client->createMonitoredItems($sub->subscriptionId, [
    ['nodeId' => 'ns=2;i=1001'],
]);

$response = $client->publish();
foreach ($response->notifications as $notif) {
    echo $notif['dataValue']->getValue() . "\n";
}

$client->deleteSubscription($sub->subscriptionId);
$client->disconnect();

Auto-publish — no manual publish loop

With auto_publish enabled, the daemon handles subscriptions automatically. Just register Laravel event listeners:

// config/opcua.php
'session_manager' => ['auto_publish' => true],

'connections' => [
    'plc-1' => [
        'endpoint' => 'opc.tcp://192.168.1.10:4840',
        'auto_connect' => true,
        'subscriptions' => [
            [
                'publishing_interval' => 500.0,
                'monitored_items' => [
                    ['node_id' => 'ns=2;s=Temperature', 'client_handle' => 1],
                ],
            ],
        ],
    ],
],
// EventServiceProvider
use PhpOpcua\Client\Event\DataChangeReceived;

Event::listen(DataChangeReceived::class, function (DataChangeReceived $e) {
    DB::table('sensor_readings')->insert([
        'value' => $e->dataValue->getValue(),
        'client_handle' => $e->clientHandle,
    ]);
});
php artisan opcua:session  # connects, subscribes, publishes — all automatic

React to events

47 PSR-14 events are dispatched automatically — connections, reads, writes, alarms, subscriptions, cache, retries. Just register listeners:

use Illuminate\Support\Facades\Event;
use PhpOpcua\Client\Event\ClientConnected;
use PhpOpcua\Client\Event\NodeValueWriteFailed;
use PhpOpcua\Client\Event\AlarmActivated;

// Log connections
Event::listen(ClientConnected::class, function ($e) {
    logger()->info("Connected to {$e->endpointUrl}");
});

// Track write failures
Event::listen(NodeValueWriteFailed::class, function ($e) {
    logger()->warning("Write failed on {$e->nodeId}: 0x" . dechex($e->statusCode));
});

// Alert operators on alarms
Event::listen(AlarmActivated::class, function ($e) {
    Notification::send(
        User::role('operator')->get(),
        new AlarmTriggered($e->sourceName, $e->severity, $e->message),
    );
});

See Events documentation for the full reference of all 47 events.

Switch connections

// Named connection from config
$client = Opcua::connect('plc-line-1');
$value = $client->read('ns=2;i=1001');
Opcua::disconnect('plc-line-1');

// Ad-hoc connection at runtime
$client = Opcua::connectTo('opc.tcp://10.0.0.50:4840', [
    'username' => 'operator',
    'password' => 'secret',
], as: 'temp-plc');

Opcua::disconnectAll();

Test without a real server

use PhpOpcua\Client\Testing\MockClient;
use PhpOpcua\Client\Types\DataValue;

$mock = MockClient::create()
    ->onRead('i=2259', fn() => DataValue::ofInt32(0));

// Inject into OpcuaManager via DI or reflection
$value = $mock->read('i=2259');
echo $value->getValue(); // 0
echo $mock->callCount('read'); // 1

Features

Feature What it does
Facade Opcua::read(), Opcua::browse(), etc. with full PHPDoc for IDE autocompletion
Named Connections Define multiple servers in config/opcua.php, switch with Opcua::connection('plc-2')
Ad-hoc Connections Opcua::connectTo('opc.tcp://...') for endpoints not in config
Session Manager Artisan command php artisan opcua:session for daemon-based session persistence
Transparent Fallback Daemon available? ManagedClient. Not available? Direct Client. Zero code changes
String NodeIds 'i=2259', 'ns=2;s=MyNode' everywhere a NodeId is accepted
Fluent Builder API readMulti(), writeMulti(), createMonitoredItems(), translateBrowsePaths() chain
PSR-3 Logging Laravel's log channel injected automatically via config
PSR-14 Events 47 dispatched events covering every OPC UA operation for observability and extensibility
PSR-16 Caching Laravel's cache store injected automatically. Per-call useCache on browse ops
Write Auto-Detection write('ns=2;i=1001', 42) — omit the type and the client detects it automatically
Read Metadata Cache Cached node metadata avoids redundant reads; refresh on demand with read($nodeId, refresh: true)
Trust Store FileTrustStore with configurable TrustPolicy, auto-accept modes, and certificate management
Type Discovery discoverDataTypes() auto-detects custom server structures
Auto-Publish Daemon auto-publishes for sessions with subscriptions, dispatches PSR-14 events to Laravel listeners
Auto-Connect Per-connection auto_connect with declarative subscriptions config — daemon sets up monitoring on startup
Subscription Management createMonitoredItems(), modifyMonitoredItems(), setTriggering(), transferSubscriptions()
MockClient Test without a server — register handlers, assert calls
Timeout & Retry Per-connection timeout, auto_retry via config or fluent API
Auto-Batching readMulti/writeMulti transparently split when exceeding server limits
Recursive Browse browseAll(), browseRecursive() with depth control and cycle detection
Path Resolution resolveNodeId('/Objects/Server/ServerStatus')
Security 10 policies (RSA + ECC), 3 auth modes, auto-generated certs, certificate trust management

ECC disclaimer: ECC security policies (ECC_nistP256, ECC_nistP384, ECC_brainpoolP256r1, ECC_brainpoolP384r1) are fully implemented and tested against the OPC Foundation's UA-.NETStandard reference stack. However, no commercial OPC UA vendor supports ECC endpoints yet. When using ECC, client certificates are auto-generated if client_certificate/client_key are omitted, and username/password authentication uses the EccEncryptedSecret protocol automatically. | History Read | Raw, processed, and at-time historical queries | | Typed Returns | All service responses return public readonly DTOs |

Documentation

Full documentation is available in docs/. Highlights:

Section Covers
Getting startedOverview · Installation · Quick start · How laravel-opcua fits · Upgrading Concepts, install, first connection
ConfigurationConfig file · Connections · Environment variables · Security · Session manager · Publishing & overriding .env, config file, named connections
Using the clientFacade vs injection · Named connections · Ad-hoc connections · Connection lifecycle · Using builders Facade, DI, lifecycle
OperationsReading · Writing · Browsing · Method calls · Subscriptions · History Read/write, browse, subscribe, history
Session managerOverview · Starting the daemon · Auto-publish · Production supervisor · Monitoring Persistent sessions via daemon
EventsOverview · Connection events · Data events · Alarm events · Queued listeners PSR-14 + Laravel listeners
ObservabilityLogging · Caching · Debugging · Telescope & Pulse Logs, cache, dev tools
SecurityPolicies & modes · Credentials · Certificates · Trust store Security policies, certs, trust
TestingPest setup · Mocking the facade · Using MockClient · Integration tests Unit + integration tests
IntegrationsOctane & FrankenPHP · Horizon & queues · Broadcasting · Livewire · Notifications · Filament Laravel ecosystem
ReferenceFacade methods · OpcuaManager API · Artisan commands · Exceptions Public API
RecipesPersistent tag history · Alarm routing · Livewire dashboard · Multi-plant tenant · Companion specs · Dev with Sail · Production deployment Task-oriented walkthroughs

Testing

146+ unit tests with 99%+ code coverage. Integration tests run against uanetstandard-test-suite — a Docker-based OPC UA environment built on the OPC Foundation's UA-.NETStandard reference implementation — in both direct and managed (daemon) modes.

./vendor/bin/pest tests/Unit/                              # unit only
./vendor/bin/pest tests/Integration/ --group=integration   # integration only
./vendor/bin/pest                                          # everything

Ecosystem

Package Description
opcua-client Pure PHP OPC UA client
opcua-cli CLI tool — browse, read, write, watch, discover endpoints, manage certificates, generate code from NodeSet2.xml
opcua-session-manager Daemon-based session persistence across PHP requests. Keeps OPC UA connections alive between short-lived PHP processes via a ReactPHP daemon and Unix sockets. Separate package by design — see ROADMAP.md for rationale.
opcua-client-nodeset Pre-generated PHP types from 51 OPC Foundation companion specifications (DI, Robotics, Machinery, MachineTool, ISA-95, CNC, MTConnect, and more). 807 PHP files — NodeId constants, enums, typed DTOs, codecs, registrars with automatic dependency resolution. Just composer require and loadGeneratedTypes().
laravel-opcua Laravel integration — service provider, facade, config (this package)
uanetstandard-test-suite Docker-based OPC UA test servers (UA-.NETStandard) for integration testing

Community

Have questions, ideas, or want to share what you've built? Join the GitHub Discussions.

Connected a PLC, SCADA system, or OPC UA server? We're building a community-driven list of tested hardware and software. Share your experience in Tested Hardware & Software — even a one-liner like "Siemens S7-1500, works fine" helps other users know what to expect.

Contributing

Contributions welcome — see CONTRIBUTING.md.

AI-Ready

This package ships with machine-readable documentation designed for AI coding assistants (Claude, Cursor, Copilot, ChatGPT, and others). Feed these files to your AI so it knows how to use the library correctly:

File Purpose
llms.txt Compact project summary — architecture, Facade, configuration, session manager. Optimized for LLM context windows with minimal token usage.
llms-full.txt Comprehensive technical reference — every config key, method, DTO, event, trust store, managed client. For deep dives and complex questions.
llms-skills.md Task-oriented recipes — step-by-step instructions for common tasks (install, read, write, browse, named connections, session manager, security, testing, events). Written so an AI can generate correct, production-ready code from a user's intent.

How to use: copy the files you need into your project's AI configuration directory. The files are located in vendor/php-opcua/laravel-opcua/ after composer install.

  • Claude Code: reference per-session with --add-file vendor/php-opcua/laravel-opcua/llms-skills.md
  • Cursor: copy into your project's rules directory — cp vendor/php-opcua/laravel-opcua/llms-skills.md .cursor/rules/laravel-opcua.md
  • GitHub Copilot: copy or append the content into your project's .github/copilot-instructions.md file (create the file and directory if they don't exist). Copilot reads this file automatically for project-specific context
  • Other tools: paste the content into your system prompt, project knowledge base, or context configuration

Versioning

This package follows the same version numbering as php-opcua/opcua-client. Each release of laravel-opcua is aligned with the corresponding release of the client library to ensure full compatibility.

Changelog

See CHANGELOG.md.

License

MIT