# Test Infrastructure: OPC UA Server ## Overview The test OPC UA server uses [Azure IoT OPC PLC](https://github.com/Azure-Samples/iot-edge-opc-plc), a simulated OPC UA server that generates realistic data. It is configured with custom nodes that match ScadaLink attribute patterns. ## Image & Ports - **Image**: `mcr.microsoft.com/iotedge/opc-plc:latest` - **OPC UA endpoint**: `opc.tcp://localhost:50000` - **Web/config UI**: `http://localhost:8080` ## Startup Flags ``` --autoaccept Accept all client certificates --unsecuretransport Enable plain (non-TLS) OPC UA connections for dev tools --sph Show PLC heartbeat on console --sn=5 --sr=10 --st=uint 5 slow-changing nodes (10s cycle, uint) --fn=5 --fr=1 --ft=uint 5 fast-changing nodes (1s cycle, uint) --gn=5 5 stepping nodes --nf=/app/config/nodes.json Custom node definitions --pn=50000 Listen port ``` ## Custom Nodes The file `infra/opcua/nodes.json` defines a single `ConfigFolder` object (not an array) with a root "ScadaLink" folder containing four equipment subfolders. Tags match typical ScadaLink instance attribute patterns: | Folder | Tags | Types | |--------|------|-------| | Motor | Speed, Temperature, Current, Running, FaultCode | Double, Boolean, UInt32 | | Pump | FlowRate, Pressure, Running | Double, Boolean | | Tank | Level, Temperature, HighLevel, LowLevel | Double, Boolean | | Valve | Position, Command | Double, UInt32 | All custom nodes hold their initial/default values (0 for numerics, false for booleans) until written. OPC PLC's custom node format does not support random value generation for these nodes. Custom nodes live in namespace 3 (`http://microsoft.com/Opc/OpcPlc/`). Node IDs follow the pattern `ns=3;s=.` (e.g., `ns=3;s=Motor.Speed`). The browse path from the Objects root is: `OpcPlc > ScadaLink > Motor|Pump|Tank|Valve`. ## Verification 1. Check the container is running: ```bash docker ps --filter name=scadalink-opcua ``` 2. Verify the OPC UA endpoint using any OPC UA client (e.g., UaExpert, opcua-commander): ```bash # Using opcua-commander (npm install -g opcua-commander) opcua-commander -e opc.tcp://localhost:50000 ``` 3. Check the web UI at `http://localhost:8080` for server status and node listing. ## CLI Tool The `infra/tools/opcua_tool.py` script provides a convenient CLI for interacting with the OPC UA server. **Install dependencies** (one-time): ```bash pip install -r infra/tools/requirements.txt ``` **Commands**: ```bash # Check server status, namespaces, and endpoints python infra/tools/opcua_tool.py check # Browse the Objects folder (top-level) python infra/tools/opcua_tool.py browse # Browse a specific equipment folder python infra/tools/opcua_tool.py browse --path "3:OpcPlc.3:ScadaLink.3:Motor" # Read a tag value python infra/tools/opcua_tool.py read --node "ns=3;s=Motor.Speed" # Write a value to a tag python infra/tools/opcua_tool.py write --node "ns=3;s=Motor.Running" --value true --type Boolean # Monitor value changes for 15 seconds python infra/tools/opcua_tool.py monitor --nodes "ns=3;s=Motor.Speed,ns=3;s=Pump.FlowRate" --duration 15 ``` Use `--endpoint` to override the default endpoint (`opc.tcp://localhost:50000`). Run with `--help` for full usage. ## Relevance to ScadaLink Components - **Data Connection Layer** — connect to this server to test OPC UA subscription, read/write, and reconnection behavior. - **Site Runtime / Instance Actors** — deploy instances with tag mappings pointing at these nodes. - **Template Engine** — design templates with attributes matching the Motor/Pump/Tank/Valve folder structure.