# OPC UA read task

> Read the values of OPC UA nodes at a fixed rate and record them in channels.

An OPC UA read task reads the values of nodes on a server at a fixed rate and records them in channels. For example, it can record the tank pressures and pump speeds of a PLC 50 times a second. The Driver times each read in software.

Before you start, you need a [connected OPC UA server](https://docs.synnaxlabs.com/reference/hardware/opc-ua/connect-server).

## Node IDs

Each channel of the task reads one node. A node ID has the form `NS=<namespace>;<type>=<identifier>`:

| Type | Identifier | Example                                       |
| ---- | ---------- | --------------------------------------------- |
| `I`  | A number   | `NS=2;I=1001`                                 |
| `S`  | A string   | `NS=2;S=Tank1.Pressure`                       |
| `G`  | A GUID     | `NS=2;G=09087e75-8e5e-499b-954f-f2a9603db28a` |

Write `NS` and the type in uppercase. The Driver rejects `ns=2;s=Tank1.Pressure`. The browser in the Console fills the node IDs for you.

## Create an OPC UA read task

[Enterprise](https://docs.synnaxlabs.com/reference/get-started/editions "Needs Synnax Enterprise")

**Console**

1. In the devices toolbar, right-click the server and select **Create read task**.
2. Set **Sample rate** and **Stream rate**.
3. In the **Browser**, expand the folders of the server.
4. Drag the variables to read into **Channels**. You can select more than one.
5. Click (**Start**).

The Console creates a channel for each node, named from the browse name of the node. To choose a name, edit the name of the channel before you start. The Console also creates an index channel named `<server>_time_for_<task>`, unless one of the channels already has an index or you [use server timestamps](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#use-server-timestamps).

[](https://synnax.nyc3.cdn.digitaloceanspaces.com/docs/hardware/opc-ua/read-task-dark.mp4#t=0.001)

**Python**

Python does not create channels. Create an index channel and a channel for each node first.

```python
import synnax as sy
from synnax import opcua

server = client.devices.retrieve(name="Line 1 PLC")
time = client.channels.create(
    name="plc_time", is_index=True, data_type=sy.DataType.TIMESTAMP
)
pressure = client.channels.create(
    name="tank_1_pressure", index=time.key, data_type=sy.DataType.FLOAT64
)

task = opcua.ReadTask(
    name="Line 1 PLC read",
    device=server.key,
    sample_rate=50,
    stream_rate=25,
    channels=[
        opcua.ReadChannel(channel=pressure.key, node_id="NS=2;S=Tank1.Pressure")
    ],
)
client.tasks.configure(task)
task.start()
```

Always pass `sample_rate` and `stream_rate`. In Python they default to 10 Hz and 5 Hz, not to the Console defaults.

**TypeScript**

TypeScript does not create channels. Create an index channel and a channel for each node first.

```typescript
import { opcua } from "@synnaxlabs/client";

const [server] = await client.devices.retrieve({ names: ["Line 1 PLC"] });
const time = await client.channels.create({
  name: "plc_time",
  isIndex: true,
  dataType: "timestamp",
});
const pressure = await client.channels.create({
  name: "tank_1_pressure",
  index: time.key,
  dataType: "float64",
});

const task = await client.tasks.create({
  name: "Line 1 PLC read",
  rack: server.rack,
  type: "opc_read",
  config: opcua.readConfigZ.parse({
    device: server.key,
    sampleRate: 50,
    streamRate: 25,
    channels: [{ channel: pressure.key, nodeId: "NS=2;S=Tank1.Pressure" }],
  }),
});
await task.start();
```

## Read arrays

Some servers buffer fast samples in an array node. To read the arrays:

1. Turn on **Array sampling**.
2. Set **Array size** to the number of values in each array.

The Driver then reads each node `Sample rate / Array size` times a second, and spreads the timestamps of the values evenly over the read period. **Sample rate** must be equal to or more than **Array size**. Each array must have exactly **Array size** values, or the Driver drops the frame and shows a warning. **Stream rate** does not apply in array mode.

## Use server timestamps

By default, the Driver gives the values of each read the time halfway through the read request. To use the time from the server instead:

1. Add a node with a DateTime value, such as the source time of the PLC, to the task.
2. Turn on **Use as index** for that channel.

The Driver then uses the value of that node as the timestamp of every channel in the task. Only one channel can be the index.

## Task options

| Console label  | Python field           | Default                 | Notes                                                                                           |
| -------------- | ---------------------- | ----------------------- | ----------------------------------------------------------------------------------------------- |
| OPC UA server  | `device`               |                         | The key of the server.                                                                          |
| Sample rate    | `sample_rate`          | 50 Hz (10 Hz in Python) | Reads per second. At most 10,000.                                                               |
| Stream rate    | `stream_rate`          | 25 Hz (5 Hz in Python)  | Frames per second sent to the Core. At most the sample rate. Not in array mode.                 |
| Array sampling | `array_mode`           | Off                     | See [read arrays](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#read-arrays). |
| Array size     | `array_size`           | 1                       | Values in each array node.                                                                      |
| Data saving    | `data_saving_disabled` | On                      | See [data saving](https://docs.synnaxlabs.com/reference/hardware/tasks#data-saving).            |
| Auto start     | `auto_start`           | Off                     | Starts the task each time the Driver starts.                                                    |

TypeScript uses the same fields in camel case, such as `sampleRate`. See [timing](https://docs.synnaxlabs.com/reference/hardware/tasks#timing).

## Channel reference

The table shows the Console label of each setting, with its Python field under it.

| Setting                 | Default   | Notes                                                                                                                                           |
| ----------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Channel name `name`     | Empty     | The name of the channel that the Console creates.                                                                                               |
| `channel`               |           | The key of the channel that records the values.                                                                                                 |
| Node ID `node_id`       |           | See [node IDs](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#node-ids).                                                       |
| Node name `node_name`   | Empty     | The browse name. For display only.                                                                                                              |
| `data_type`             | `float32` | The data type of the channel that the Console creates.                                                                                          |
| Use as index `is_index` | Off       | Shows only for a DateTime node. See [server timestamps](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#use-server-timestamps). |
| Enabled `disabled`      | Off       | A disabled channel is not read.                                                                                                                 |

### Data types

The Console creates each channel with the data type of its node:

| OPC UA type | Synnax data type |
| ----------- | ---------------- |
| Boolean     | `uint8`          |
| SByte       | `int8`           |
| Byte        | `uint8`          |
| Int16       | `int16`          |
| UInt16      | `uint16`         |
| Int32       | `int32`          |
| UInt32      | `uint32`         |
| Int64       | `int64`          |
| UInt64      | `uint64`         |
| Float       | `float32`        |
| Double      | `float64`        |
| String      | `string`         |
| DateTime    | `timestamp`      |
| Guid        | `uuid`           |

## Troubleshooting

* [Invalid NodeId format](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#invalid-nodeid-format)

  * Cause

    The node ID is not in the form `NS=<namespace>;<type>=<identifier>`.

  * Fix

    Write `NS` and the type in uppercase.

* [... (NS=...): The node id refers to a node that does not exist in the server address space.](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#ns-the-node-id-refers-to-a-node-that-does-not-exist-in-the-serve)

  * Cause

    The server has no node with that ID.

  * Fix

    Drag the node from the **Browser** again.

* [OPC UA array for ... is too small](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#opc-ua-array-for-is-too-small)[... is too large](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#opc-ua-array-for-is-too-small)

  * Cause

    An array node has a different number of values than **Array size**.

  * Fix

    Set **Array size** to the length of the array.

* [Skipped invalid data](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#skipped-invalid-data)

  * Cause

    The server sent a value that the Driver cannot convert. The Driver skips the frame.

  * Fix

    Check the data type of the node.

* [Channel ... already exists as ...](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#channel-already-exists-as)

  * Cause

    Another task already reads the node into that channel.

  * Fix

    Move the channels to one task.

* [Failed to browse OPC UA nodes](https://docs.synnaxlabs.com/reference/hardware/opc-ua/read-task#failed-to-browse-opc-ua-nodes)

  * Cause

    The Driver could not browse the server.

  * Fix

    Check the [server connection](https://docs.synnaxlabs.com/reference/hardware/opc-ua/connect-server#troubleshooting).

For other problems, see [Troubleshoot hardware](https://docs.synnaxlabs.com/reference/hardware/troubleshooting).
